Ejemplo n.º 1
0
def bspline_param(vectormap, depvar):
    """Get output bspline parameter estimates"""
    stfact = Module("v.surf.bspline",
                    flags="ec",
                    input=vectormap,
                    column=depvar,
                    memory=1024,
                    stdout_=PIPE).outputs.stdout
    stepdist = float(stfact.split(':')[-1].strip())
    stfact = Module("v.surf.bspline",
                    flags="c",
                    input=vectormap,
                    ew_step=stepdist,
                    ns_step=stepdist,
                    column=depvar,
                    memory=1024,
                    stdout_=PIPE).outputs.stdout
    stfact = stfact.replace(" ", "")
    stfact = stfact.split("\n")[1:-1]
    stfact = [z.split("|") for z in stfact]
    stfact = [[float(x) for x in y if x != ''] for y in stfact]
    minlambda = min(stfact, key=lambda x: abs(x[1]))[0]
    return (stepdist, minlambda)
Ejemplo n.º 2
0
def main(options, flags):

    # Variables
    raster_cat = options["raster"]
    raster_cat = raster_cat.split(",")
    raster_cat_names = [z.split("@")[0] for z in raster_cat]
    raster_cat_names = [x.lower() for x in raster_cat_names]
    raster_cont = options["raster2"]
    raster_cont = raster_cont.split(",")
    raster_cont_names = [z.split("@")[0] for z in raster_cont]
    raster_cont_names = [x.lower() for x in raster_cont_names]
    input_vector = options["vector"]
    output_vector = options["output"]

    if flags["o"]:
        tmp_layer = tmpname()
        Module("g.copy", vector=[input_vector, output_vector], quiet=True)
    else:
        tmp_layer = output_vector
    # Create vector with column names
    base_column_names = ["x double precision, y double precision, label integer"]
    for i, raster_name in enumerate(raster_cat):
        data_types = gs.parse_command("r.info", flags="g", map=raster_name, quiet=True)[
            "datatype"
        ]
        if data_types == "CELL":
            base_column_names.append(
                "{0}_ID integer, {0} varchar(255)".format(raster_cat_names[i])
            )
        else:
            base_column_names.append(
                "ID_{0} double precision, {0} varchar(255)".format(raster_cat_names[i])
            )
    column_names = ",".join(base_column_names)

    # Get raster points of raster layers with labels
    # Export point map to text file first and use that as input in r.what
    point_to_ascii = Module(
        "v.out.ascii",
        input=input_vector,
        format="point",
        separator="space",
        precision=12,
        stdout_=PIPE,
    ).outputs.stdout
    raster_cats = Module(
        "r.what", flags="f", map=raster_cat, stdin_=point_to_ascii, stdout_=PIPE
    ).outputs.stdout
    ascii_to_point = raster_cats.replace("|*|", "||").replace("\r", "")
    Module(
        "v.in.ascii",
        input="-",
        stdin_=ascii_to_point,
        output=tmp_layer,
        columns=column_names,
        separator="pipe",
        format="point",
        x=1,
        y=2,
        quiet=True,
    )

    # In- or exclude coordinates
    if not flags["c"]:
        Module("v.db.dropcolumn", map=tmp_layer, columns=["x", "y"])
    # Get raster points of raster layers without labels (optional)
    if options["raster2"]:
        for j, raster_cont_values in enumerate(raster_cont):
            Module(
                "v.what.rast",
                map=tmp_layer,
                raster=raster_cont_values,
                column=raster_cont_names[j],
                quiet=True,
            )
    # Join table of original layer (and drop label columns)

    if flags["o"]:

        cols = Module("db.columns", table=tmp_layer, stdout_=PIPE).outputs.stdout.split(
            "\n"
        )
        cols.pop()
        del cols[:1]

        sqlstat = "CREATE INDEX {0}_label ON {0} (label);".format(tmp_layer)
        Module("db.execute", sql=sqlstat)
        Module(
            "v.db.join",
            map=output_vector,
            column="cat",
            other_table=tmp_layer,
            other_column="label",
            subset_columns=cols,
        )
    # Remove label column
    Module("v.db.dropcolumn", map=output_vector, columns=["label"])

    # Write metadata
    gs.vector_history(output_vector, replace=True)
Ejemplo n.º 3
0
def main(options, flags):

    gisbase = os.getenv('GISBASE')
    if not gisbase:
        gs.fatal(_('$GISBASE not defined'))
        return 0

    # Variables
    RAST = options['raster']
    RAST = RAST.split(',')
    RASTL = [z.split('@')[0] for z in RAST]
    RASTL = [x.lower() for x in RASTL]
    RAST2 = options['raster2']
    RAST2 = RAST2.split(',')
    RASTL2 = [z.split('@')[0] for z in RAST2]
    RASTL2 = [x.lower() for x in RASTL2]
    VECT = options['vector']
    OUTP = options['output']

    # Create vector with column names
    CT = ['x double precision, y double precision, label integer']
    for i in xrange(len(RAST)):
        DT = gs.parse_command('r.info', flags='g', map=RAST[i],
                              quiet=True)['datatype']
        if DT == 'CELL':
            CT.append("ID_{0} integer, {0} varchar(255)".format(RASTL[i]))
        else:
            CT.append("ID_{0} double precision, {0} varchar(255)".format(
                RASTL[i]))
    CNT = ','.join(CT)

    # Get raster points of raster layers with labels
    # Export point map to text file first and use that as input in r.what
    # TODO: the above is workaround to get vector cat value as label. Easier,
    # would be to use vector point map directly as input, but that does not
    # give label to link back to old vector layer
    PAT = Module('v.out.ascii',
                 input=VECT,
                 format='point',
                 separator='space',
                 precision=12,
                 stdout_=PIPE).outputs.stdout
    CAT = Module('r.what', flags='f', map=RAST, stdin_=PAT,
                 stdout_=PIPE).outputs.stdout
    CATV = CAT.replace('|*|', '||')
    Module('v.in.ascii',
           input='-',
           stdin_=CATV,
           output=OUTP,
           columns=CNT,
           separator='pipe',
           format='point',
           x=1,
           y=2,
           quiet=True)

    # Get raster points of raster layers without labels (optional)
    if options['raster2']:
        for j in xrange(len(RAST2)):
            DT = gs.parse_command('r.info',
                                  flags='g',
                                  map=RAST2[j],
                                  quiet=True)['datatype']
            if DT == 'CELL':
                CT = "{} integer".format(RASTL2[j])
            else:
                CT = "{} double precision".format(RASTL2[j])
            Module('v.db.addcolumn', map=OUTP, columns=CT)
            Module('v.what.rast', map=OUTP, raster=RAST2[j], column=RASTL2[j])

    # Write metadata
    opt2 = dict((k, v) for k, v in options.iteritems() if v)
    hist = ' '.join("{!s}={!r}".format(k, v) for (k, v) in opt2.iteritems())
    hist = "v.what.rastlabel {}".format(hist)
    Module('v.support',
           map=OUTP,
           comment="created with v.what.rastlabel",
           cmdhist=hist,
           flags='r',
           quiet=True)
Ejemplo n.º 4
0
def main(options, flags):

    gisbase = os.getenv("GISBASE")
    if not gisbase:
        gs.fatal(_("$GISBASE not defined"))
        return 0

    # Reference / sample area or points
    ref_rast = options["ref_rast"]
    ref_vect = options["ref_vect"]
    if ref_rast:
        reftype = gs.raster_info(ref_rast)
        if reftype["datatype"] != "CELL":
            gs.fatal(_("The ref_rast map must have type CELL (integer)"))
        if (reftype["min"] != 0 and reftype["min"] != 1) or reftype["max"] != 1:
            gs.fatal(
                _(
                    "The ref_rast map must be a binary raster,"
                    " i.e. it should contain only values 0 and 1 or 1 only"
                    " (now the minimum is {} and maximum is {})".format(
                        reftype["min"], reftype["max"]
                    )
                )
            )

    # old environmental layers & variable names
    reference_layer = options["env"]
    reference_layer = reference_layer.split(",")
    raster_exists(reference_layer)
    variable_name = [z.split("@")[0] for z in reference_layer]
    variable_name = [x.lower() for x in variable_name]

    # new environmental variables
    projection_layers = options["env_proj"]
    if not projection_layers:
        to_be_projected = False
        projection_layers = reference_layer
    else:
        to_be_projected = True
        projection_layers = projection_layers.split(",")
        raster_exists(projection_layers)
        if (
            len(projection_layers) != len(reference_layer)
            and len(projection_layers) != 0
        ):
            gs.fatal(
                _(
                    "The number of reference and predictor variables"
                    " should be the same. You provided {} reference and {}"
                    " projection variables".format(
                        len(reference_layer), len(projection_layers)
                    )
                )
            )

    # output layers
    opl = options["output"]
    opc = opl + "_MES"
    ipi = [opl + "_" + i for i in variable_name]

    # flags
    flm = flags["m"]
    flk = flags["k"]
    fln = flags["n"]
    fli = flags["i"]
    flc = flags["c"]

    # digits / precision
    digits = int(options["digits"])
    digits2 = pow(10, digits)

    # get current region settings, to compare to new ones later
    region_1 = gs.parse_command("g.region", flags="g")

    # Text for history in metadata
    opt2 = dict((k, v) for k, v in options.items() if v)
    hist = " ".join("{!s}={!r}".format(k, v) for (k, v) in opt2.items())
    hist = "r.mess {}".format(hist)
    unused, tmphist = tempfile.mkstemp()
    with open(tmphist, "w") as text_file:
        text_file.write(hist)

    # Create reference layer if not defined
    if not ref_rast and not ref_vect:
        ref_rast = tmpname("tmp0")
        Module(
            "r.mapcalc",
            "{0} = if(isnull({1}),null(),1)".format(ref_rast, reference_layer[0]),
            quiet=True,
        )

    # Create the recode table - Reference distribution is raster
    citiam = gs.find_file(name="MASK", element="cell", mapset=gs.gisenv()["MAPSET"])
    if citiam["fullname"]:
        rname = tmpname("tmp3")
        Module("r.mapcalc", expression="{} = MASK".format(rname), quiet=True)

    if ref_rast:
        vtl = ref_rast

        # Create temporary layer based on reference layer
        tmpf0 = tmpname("tmp2")
        Module(
            "r.mapcalc", expression="{0} = int({1} * 1)".format(tmpf0, vtl), quiet=True
        )
        Module("r.null", map=tmpf0, setnull=0, quiet=True)
        if citiam["fullname"]:
            Module("r.mask", flags="r", quiet=True)
        for i in range(len(reference_layer)):

            # Create mask based on combined MASK/reference layer
            Module("r.mask", raster=tmpf0, quiet=True)

            # Calculate the frequency distribution
            tmpf1 = tmpname("tmp4")
            Module(
                "r.mapcalc",
                expression="{0} = int({1} * {2})".format(
                    tmpf1, digits2, reference_layer[i]
                ),
                quiet=True,
            )
            stats_out = Module(
                "r.stats",
                flags="cn",
                input=tmpf1,
                sort="asc",
                separator=";",
                stdout_=PIPE,
            ).outputs.stdout
            stval = {}
            stats_outlines = stats_out.replace("\r", "").split("\n")
            stats_outlines = [_f for _f in stats_outlines if _f]
            for z in stats_outlines:
                [val, count] = z.split(";")
                stval[float(val)] = float(count)
            sstval = sorted(stval.items(), key=operator.itemgetter(0))
            sstval = np.matrix(sstval)
            a = np.cumsum(np.array(sstval), axis=0)
            b = np.sum(np.array(sstval), axis=0)
            c = a[:, 1] / b[1] * 100

            # Remove tmp mask and set region to env_proj if needed
            Module("r.mask", quiet=True, flags="r")
            if to_be_projected:
                gs.use_temp_region()
                Module("g.region", quiet=True, raster=projection_layers[0])

            # get new region settings, to compare to original ones later
            region_2 = gs.parse_command("g.region", flags="g")

            # Get min and max values for recode table (based on full map)
            tmpf2 = tmpname("tmp5")
            Module(
                "r.mapcalc",
                expression="{0} = int({1} * {2})".format(
                    tmpf2, digits2, projection_layers[i]
                ),
                quiet=True,
            )
            d = gs.parse_command("r.univar", flags="g", map=tmpf2, quiet=True)

            # Create recode rules
            Dmin = int(d["min"])
            Dmax = int(d["max"])
            envmin = np.min(np.array(sstval), axis=0)[0]
            envmax = np.max(np.array(sstval), axis=0)[0]

            if Dmin < envmin:
                e1 = Dmin - 1
            else:
                e1 = envmin - 1
            if Dmax > envmax:
                e2 = Dmax + 1
            else:
                e2 = envmax + 1

            a1 = np.hstack([(e1), np.array(sstval.T[0])[0, :]])
            a2 = np.hstack([np.array(sstval.T[0])[0, :] - 1, (e2)])
            b1 = np.hstack([(0), c])

            fd2, tmprule = tempfile.mkstemp(suffix=variable_name[i])
            with open(tmprule, "w") as text_file:
                for k in np.arange(0, len(b1.T)):
                    text_file.write(
                        "%s:%s:%s\n" % (str(int(a1[k])), str(int(a2[k])), str(b1[k]))
                    )

            # Create the recode layer and calculate the IES
            compute_ies(tmprule, ipi[i], tmpf2, envmin, envmax)
            Module(
                "r.support",
                map=ipi[i],
                title="IES {}".format(reference_layer[i]),
                units="0-100 (relative score)",
                description="Environmental similarity {}".format(reference_layer[i]),
                loadhistory=tmphist,
            )

            # Clean up
            os.close(fd2)
            os.remove(tmprule)

            # Change region back to original
            gs.del_temp_region()

    # Create the recode table - Reference distribution is vector
    else:
        vtl = ref_vect

        # Copy point layer and add columns for variables
        tmpf0 = tmpname("tmp7")
        Module(
            "v.extract", quiet=True, flags="t", input=vtl, type="point", output=tmpf0
        )
        Module("v.db.addtable", quiet=True, map=tmpf0)

        # TODO: see if there is a more efficient way to handle the mask
        if citiam["fullname"]:
            Module("r.mask", quiet=True, flags="r")

        # Upload raster values and get value in python as frequency table
        sql1 = "SELECT cat FROM {}".format(str(tmpf0))
        cn = len(np.hstack(db.db_select(sql=sql1)))
        for m in range(len(reference_layer)):

            # Set mask back (this means that points outside the mask will
            # be ignored in the computation of the frequency distribution
            # of the reference variabele env(m))
            if citiam["fullname"]:
                Module("g.copy", raster=[rname, "MASK"], quiet=True)

            # Compute frequency distribution of variable(m)
            mid = str(m)
            laytype = gs.raster_info(reference_layer[m])["datatype"]
            if laytype == "CELL":
                columns = "envvar_{} integer".format(str(mid))
            else:
                columns = "envvar_{} double precision".format(str(mid))
            Module("v.db.addcolumn", map=tmpf0, columns=columns, quiet=True)
            sql2 = "UPDATE {} SET envvar_{} = NULL".format(str(tmpf0), str(mid))
            Module("db.execute", sql=sql2, quiet=True)
            coln = "envvar_{}".format(str(mid))
            Module(
                "v.what.rast",
                quiet=True,
                map=tmpf0,
                layer=1,
                raster=reference_layer[m],
                column=coln,
            )
            sql3 = (
                "SELECT {0}, count({0}) from {1} WHERE {0} IS NOT NULL "
                "GROUP BY {0} ORDER BY {0}"
            ).format(coln, tmpf0)
            volval = np.vstack(db.db_select(sql=sql3))
            volval = volval.astype(np.float, copy=False)
            a = np.cumsum(volval[:, 1], axis=0)
            b = np.sum(volval[:, 1], axis=0)
            c = a / b * 100

            # Check for point without values
            if b < cn:
                gs.info(
                    _(
                        "Please note that there were {} points without "
                        "value. This is probably because they are outside "
                        "the computational region or mask".format((cn - b))
                    )
                )

            # Set region to env_proj layers (if different from env) and remove
            # mask (if set above)
            if citiam["fullname"]:
                Module("r.mask", quiet=True, flags="r")
            if to_be_projected:
                gs.use_temp_region()
                Module("g.region", quiet=True, raster=projection_layers[0])
            region_2 = gs.parse_command("g.region", flags="g")

            # Multiply env_proj layer with dignum
            tmpf2 = tmpname("tmp8")
            Module(
                "r.mapcalc",
                expression="{0} = int({1} * {2})".format(
                    tmpf2, digits2, projection_layers[m]
                ),
                quiet=True,
            )

            # Calculate min and max values of sample points and raster layer
            envmin = int(min(volval[:, 0]) * digits2)
            envmax = int(max(volval[:, 0]) * digits2)
            Drange = gs.read_command("r.info", flags="r", map=tmpf2)
            Drange = str.splitlines(Drange)
            Drange = np.hstack([i.split("=") for i in Drange])
            Dmin = int(Drange[1])
            Dmax = int(Drange[3])

            if Dmin < envmin:
                e1 = Dmin - 1
            else:
                e1 = envmin - 1
            if Dmax > envmax:
                e2 = Dmax + 1
            else:
                e2 = envmax + 1

            a0 = volval[:, 0] * digits2
            a0 = a0.astype(np.int, copy=False)
            a1 = np.hstack([(e1), a0])
            a2 = np.hstack([a0 - 1, (e2)])
            b1 = np.hstack([(0), c])

            fd3, tmprule = tempfile.mkstemp(suffix=variable_name[m])
            with open(tmprule, "w") as text_file:
                for k in np.arange(0, len(b1)):
                    rtmp = "{}:{}:{}\n".format(
                        str(int(a1[k])), str(int(a2[k])), str(b1[k])
                    )
                    text_file.write(rtmp)

            # Create the recode layer and calculate the IES
            compute_ies(tmprule, ipi[m], tmpf2, envmin, envmax)
            Module(
                "r.support",
                map=ipi[m],
                title="IES {}".format(reference_layer[m]),
                units="0-100 (relative score)",
                description="Environmental similarity {}".format(reference_layer[m]),
                loadhistory=tmphist,
            )

            # Clean up
            os.close(fd3)
            os.remove(tmprule)

            # Change region back to original
            gs.del_temp_region()

    # Calculate MESS statistics
    # Set region to env_proj layers (if different from env)
    # Note: this changes the region, to ensure the newly created layers
    # are actually visible to the user. This goes against normal practise
    # There will be a warning.
    if to_be_projected:
        Module("g.region", quiet=True, raster=projection_layers[0])

    # MES
    Module("r.series", quiet=True, output=opc, input=ipi, method="minimum")
    gs.write_command("r.colors", map=opc, rules="-", stdin=COLORS_MES, quiet=True)

    # Write layer metadata
    Module(
        "r.support",
        map=opc,
        title="Areas with novel conditions",
        units="0-100 (relative score)",
        description="The multivariate environmental similarity" "(MES)",
        loadhistory=tmphist,
    )

    # Area with negative MES
    if fln:
        mod1 = "{}_novel".format(opl)
        Module("r.mapcalc", "{} = int(if( {} < 0, 1, 0))".format(mod1, opc), quiet=True)

        # Write category labels
        Module("r.category", map=mod1, rules="-", stdin=RECL_MESNEG, quiet=True)

        # Write layer metadata
        Module(
            "r.support",
            map=mod1,
            title="Areas with novel conditions",
            units="-",
            source1="Based on {}".format(opc),
            description="1 = novel conditions, 0 = within range",
            loadhistory=tmphist,
        )

    # Most dissimilar variable (MoD)
    if flm:
        tmpf4 = tmpname("tmp9")
        mod2 = "{}_MoD".format(opl)
        Module("r.series", quiet=True, output=tmpf4, input=ipi, method="min_raster")
        Module("r.mapcalc", "{} = int({})".format(mod2, tmpf4), quiet=True)

        fd4, tmpcat = tempfile.mkstemp()
        with open(tmpcat, "w") as text_file:
            for cats in range(len(ipi)):
                text_file.write("{}:{}\n".format(str(cats), reference_layer[cats]))
        Module("r.category", quiet=True, map=mod2, rules=tmpcat, separator=":")
        os.close(fd4)
        os.remove(tmpcat)

        # Write layer metadata
        Module(
            "r.support",
            map=mod2,
            title="Most dissimilar variable (MoD)",
            units="-",
            source1="Based on {}".format(opc),
            description="Name of most dissimilar variable",
            loadhistory=tmphist,
        )

    # sum(IES), where IES < 0
    if flk:
        mod3 = "{}_SumNeg".format(opl)
        c0 = -0.01 / digits2
        Module(
            "r.series",
            quiet=True,
            input=ipi,
            method="sum",
            range=("-inf", c0),
            output=mod3,
        )
        gs.write_command("r.colors", map=mod3, rules="-", stdin=COLORS_MES, quiet=True)

        # Write layer metadata
        Module(
            "r.support",
            map=mod3,
            title="Sum of negative IES values",
            units="-",
            source1="Based on {}".format(opc),
            description="Sum of negative IES values",
            loadhistory=tmphist,
        )

    # Number of layers with negative values
    if flc:
        tmpf5 = tmpname("tmp10")
        mod4 = "{}_CountNeg".format(opl)
        MinMes = gs.read_command("r.info", quiet=True, flags="r", map=opc)
        MinMes = str.splitlines(MinMes)
        MinMes = float(np.hstack([i.split("=") for i in MinMes])[1])
        c0 = -0.0001 / digits2
        Module(
            "r.series",
            quiet=True,
            input=ipi,
            output=tmpf5,
            method="count",
            range=(MinMes, c0),
        )
        gs.mapcalc("$mod4 = int($tmpf5)", mod4=mod4, tmpf5=tmpf5, quiet=True)

        # Write layer metadata
        Module(
            "r.support",
            map=mod4,
            title="Number of layers with negative values",
            units="-",
            source1="Based on {}".format(opc),
            description="Number of layers with negative values",
            loadhistory=tmphist,
        )

    # Remove IES layers
    if fli:
        Module("g.remove", quiet=True, flags="f", type="raster", name=ipi)
    # Clean up tmp file
    # os.remove(tmphist)

    gs.message(_("Finished ...\n"))
    if region_1 != region_2:
        gs.message(
            _(
                "\nPlease note that the region has been changes to match"
                " the set of projection (env_proj) variables.\n"
            )
        )
Ejemplo n.º 5
0
def main(options, flags):

    # Check if running in GRASS
    gisbase = os.getenv("GISBASE")
    if not gisbase:
        gs.fatal(_("$GISBASE not defined"))
        return 0

    # variables
    ipl = options["env"]
    ipl = ipl.split(",")
    raster_exists(ipl)
    ipn = [z.split("@")[0] for z in ipl]
    ipn = [x.lower() for x in ipn]
    out = options["output"]
    if out:
        tmpf0 = out
    else:
        tmpf0 = tmpname("reb0")
    filename = options["file"]
    ref = options["ref"]
    flag_m = flags["m"]
    flag_n = flags["n"]
    flag_o = flags["o"]
    flag_i = flags["i"]
    digits = int(options["digits"])
    digits2 = pow(10, digits)

    # Check if ref map is of type cell and values are limited to 1 and 0
    reftype = gs.raster_info(ref)
    if reftype["datatype"] != "CELL":
        gs.fatal(_("Your reference map must have type CELL (integer)"))
    if reftype["min"] != 0 or reftype["max"] != 1:
        gs.fatal(
            _("The input raster map must be a binary raster,"
              " i.e. it should contain only values 0 and 1 "
              " (now the minimum is %d and maximum is %d)") %
            (reftype["min"], reftype["max"]))

    # Text for history in metadata
    opt2 = dict((k, v) for k, v in options.items() if v)
    hist = " ".join("{!s}={!r}".format(k, v) for (k, v) in opt2.items())
    hist = "r.meb {}".format(hist)
    unused, tmphist = tempfile.mkstemp()
    text_file = open(tmphist, "w")
    text_file.write(hist)
    text_file.close()

    # ------------------------------------------------------------------------
    # Compute MES
    # ------------------------------------------------------------------------

    # Create temporary copy of ref layer
    tmpref0 = tmpname("reb1")
    CLEAN_RAST.append(tmpref0)
    gs.run_command("g.copy", quiet=True, raster=(ref, tmpref0))

    ipi = []
    for j in range(len(ipl)):
        # Calculate the frequency distribution
        tmpf1 = tmpname("reb1")
        CLEAN_RAST.append(tmpf1)
        laytype = gs.raster_info(ipl[j])["datatype"]
        if laytype == "CELL":
            gs.run_command("g.copy", quiet=True, raster=(ipl[j], tmpf1))
        else:
            gs.mapcalc(
                "$tmpf1 = int($dignum * $inplay)",
                tmpf1=tmpf1,
                inplay=ipl[j],
                dignum=digits2,
                quiet=True,
            )
        stats_out = Module(
            "r.stats",
            flags="cn",
            input=tmpf1,
            sort="asc",
            separator=";",
            stdout_=PIPE,
        ).outputs.stdout
        stval = {}
        stats_outlines = stats_out.replace("\r", "").split("\n")
        stats_outlines = [_f for _f in stats_outlines if _f]
        for z in stats_outlines:
            [val, count] = z.split(";")
            stval[float(val)] = float(count)
        sstval = sorted(stval.items(), key=operator.itemgetter(0))
        sstval = np.matrix(sstval)
        a = np.cumsum(np.array(sstval), axis=0)
        b = np.sum(np.array(sstval), axis=0)
        c = a[:, 1] / b[1] * 100

        # Create recode rules
        e1 = np.min(np.array(sstval), axis=0)[0] - 99999
        e2 = np.max(np.array(sstval), axis=0)[0] + 99999
        a1 = np.hstack([(e1), np.array(sstval.T[0])[0, :]])
        a2 = np.hstack([np.array(sstval.T[0])[0, :] - 1, (e2)])
        b1 = np.hstack([(0), c])

        fd2, tmprule = tempfile.mkstemp()
        text_file = open(tmprule, "w")
        for k in np.arange(0, len(b1.T)):
            text_file.write("{}:{}:{}\n".format(int(a1[k]), int(a2[k]), b1[k]))
        text_file.close()

        # Create the recode layer and calculate the IES
        tmpf2 = tmpname("reb2")
        CLEAN_RAST.append(tmpf2)
        gs.run_command("r.recode", input=tmpf1, output=tmpf2, rules=tmprule)

        tmpf3 = tmpname("reb3")
        CLEAN_RAST.append(tmpf3)

        calcc = ("{1} = if({0} <= 50, 2 * float({0}), if({0} < 100, "
                 "2 * (100 - float({0}))))".format(tmpf2, tmpf3))
        gs.mapcalc(calcc, quiet=True)
        gs.run_command("g.remove",
                       quiet=True,
                       flags="f",
                       type="raster",
                       name=(tmpf2, tmpf1))
        os.close(fd2)
        ipi.append(tmpf3)

    # ----------------------------------------------------------------------
    # Calculate EB statistics
    # ----------------------------------------------------------------------

    # EB MES
    if flag_m:
        gs.info(_("\nThe EB based on mean ES values:\n"))
        nmn = "{}_MES_mean".format(tmpf0)
        gs.run_command("r.series",
                       quiet=True,
                       output=nmn,
                       input=tuple(ipi),
                       method="average")
        gs.write_command("r.colors",
                         map=nmn,
                         rules="-",
                         stdin=COLORS_MES,
                         quiet=True)
        ebm = EB(simlay=nmn, reflay=tmpref0)
        if not out:
            # Add to list of layers to be removed at completion
            CLEAN_RAST.append(nmn)
        else:
            # Write layer metadata
            gs.run_command(
                "r.support",
                map=nmn,
                title="Multivariate environmental similarity (MES)",
                units="0-100 (relative score",
                description="MES (compuated as the average of "
                "the individual similarity layers",
                loadhistory=tmphist,
            )

    if flag_n:
        gs.info(_("\nThe EB based on median ES values:\n"))
        nmn = "{}_MES_median".format(tmpf0)
        gs.run_command("r.series",
                       quiet=True,
                       output=nmn,
                       input=tuple(ipi),
                       method="median")
        gs.write_command("r.colors",
                         map=nmn,
                         rules="-",
                         stdin=COLORS_MES,
                         quiet=True)
        ebn = EB(simlay=nmn, reflay=tmpref0)
        if not out:
            CLEAN_RAST.append(nmn)
        else:
            # Write layer metadata
            gs.run_command(
                "r.support",
                map=nmn,
                title="Multivariate environmental similarity (MES)",
                units="0-100 (relative score",
                description="MES (compuated as the median of "
                "the individual similarity layers",
                loadhistory=tmphist,
            )

    if flag_o:
        gs.info(_("\nThe EB based on minimum ES values:\n"))
        nmn = "{}_MES_minimum".format(tmpf0)
        gs.run_command("r.series",
                       quiet=True,
                       output=nmn,
                       input=tuple(ipi),
                       method="minimum")
        gs.write_command("r.colors",
                         map=nmn,
                         rules="-",
                         stdin=COLORS_MES,
                         quiet=True)
        ebo = EB(simlay=nmn, reflay=tmpref0)
        if not out:
            CLEAN_RAST.append(nmn)
        else:
            # Write layer metadata
            gs.run_command(
                "r.support",
                map=nmn,
                title="Multivariate environmental similarity (MES)",
                units="0-100 (relative score",
                description="MES (compuated as the minimum of "
                "the individual similarity layers",
                loadhistory=tmphist,
            )

    # EB individual layers
    if flag_i:
        ebi = {}
        for mm in range(len(ipi)):
            nmn = "{}_{}".format(tmpf0, ipn[mm])
            if not out:
                CLEAN_RAST.append(nmn)
            gs.run_command("g.rename", quiet=True, raster=(ipi[mm], nmn))
            gs.write_command("r.colors",
                             map=nmn,
                             rules="-",
                             stdin=COLORS_MES,
                             quiet=True)
            gs.info(_("\nThe EB for {}:\n").format(ipn[mm]))
            value = EB(simlay=nmn, reflay=tmpref0)
            ebi[ipn[mm]] = value
            gs.run_command(
                "r.support",
                map=nmn,
                title="Environmental similarity (ES) for "
                "{}".format(ipn[mm]),
                units="0-100 (relative score",
                description="Environmental similarity (ES) for "
                "{}".format(ipn[mm]),
                loadhistory=tmphist,
            )

    else:
        gs.run_command("g.remove",
                       quiet=True,
                       flags="f",
                       type="raster",
                       name=ipi)

    if filename:
        with open(filename, "wt") as csvfile:
            fieldnames = [
                "variable", "median_region", "median_reference", "mad", "eb"
            ]
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
            writer.writeheader()
            if flag_m:
                writer.writerow({
                    "variable": "MES_mean",
                    "median_region": ebm[1],
                    "median_reference": ebm[2],
                    "mad": ebm[0],
                    "eb": ebm[3],
                })
            if flag_n:
                writer.writerow({
                    "variable": "MES_median",
                    "median_region": ebn[1],
                    "median_reference": ebn[2],
                    "mad": ebn[0],
                    "eb": ebn[3],
                })
            if flag_o:
                writer.writerow({
                    "variable": "MES_minimum",
                    "median_region": ebo[1],
                    "median_reference": ebo[2],
                    "mad": ebo[0],
                    "eb": ebo[3],
                })
            if flag_i:
                mykeys = ebi.keys()
                for vari in mykeys:
                    ebj = ebi[vari]
                    writer.writerow({
                        "variable": vari,
                        "median_region": ebj[1],
                        "median_reference": ebj[2],
                        "mad": ebj[0],
                        "eb": ebj[3],
                    })
        gs.info(_("\nThe results are written to {}\n").format(filename))
        gs.info("\n")
Ejemplo n.º 6
0
def bspline_validation(vector,
                       column,
                       lambda_i,
                       ew_step,
                       ns_step,
                       keep,
                       npartitions=4,
                       method='bilinear',
                       solver='cholesky',
                       maxit=10000,
                       memory=2048):
    """Compute validation statistics (rsme) for bspline extrapolation"""

    # Temporary map
    tmpmap = tmpname("cvbase_")
    Module("g.copy", vector=[vector, tmpmap])

    # Compute rsme over model with all callibration points
    tmpout = tmpname("cvtmp4_")
    Module("v.surf.bspline",
           input=tmpmap,
           column=column,
           ew_step=ew_step,
           ns_step=ns_step,
           method=method,
           lambda_i=lambda_i,
           solver=solver,
           maxit=maxit,
           memory=memory,
           raster_output=tmpout)
    Module("v.what.rast", map=tmpmap, raster=tmpout, column="bspline")
    stats = Module("db.select",
                   flags="c",
                   sql="SELECT {},bspline FROM {}".format(column, tmpmap),
                   stdout_=PIPE).outputs.stdout
    stats = stats.replace("\n", "|")[:-1].split("|")
    stats = (np.asarray([float(x) for x in stats],
                        dtype="float").reshape(len(stats) / 2, 2))
    rsme_all = np.sqrt(np.mean(np.diff(stats, axis=1)**2))
    if keep:
        Module("g.rename", raster=[tmpout, keep])
    else:
        Module("g.remove", type="raster", name=tmpout, flags="f")

    # Run n-fold crossvalidation
    if npartitions > 0:
        Module("v.kcv", map=tmpmap, npartitions=npartitions)
        rsme = []
        for i in range(1, npartitions + 1):
            tmp_cal = tmpname("cvtmp_calibrate_")
            tmp_val = tmpname("cvtmp_validate_")
            tmpout1 = tmpname("cvtmp_output_1_")
            tmpout2 = tmpname("cvtmp_output_2_")
            tmpout3 = tmpname("cvtmp_output_3_")
            Module("v.extract",
                   flags="r",
                   input=tmpmap,
                   output=tmp_cal,
                   where="part={}".format(i))
            Module("v.extract",
                   input=tmpmap,
                   where="part={}".format(i),
                   output=tmp_val)
            Module("v.surf.bspline",
                   input=tmp_cal,
                   column=column,
                   ew_step=ew_step,
                   ns_step=ns_step,
                   method=method,
                   lambda_i=lambda_i,
                   solver=solver,
                   maxit=maxit,
                   memory=memory,
                   output=tmpout1,
                   sparse_input=tmp_val)
            Module("v.category",
                   input=tmpout1,
                   output=tmpout2,
                   option="del",
                   cat=-1)
            Module("v.category", input=tmpout2, output=tmpout3, option="add")
            Module("v.db.addtable", map=tmpout3)
            Module("v.db.addcolumn",
                   map=tmpout3,
                   columns=("x double precision, y double precision, "
                            "z double precision"))
            Module("v.to.db", map=tmpout3, option="coor", columns="x,y,z")
            # TODO: need to find out how to use the from_ with Module
            gs.run_command("v.distance",
                           from_=tmpout3,
                           to=tmp_val,
                           upload="to_attr",
                           column="x",
                           to_column=column)
            stats = Module("db.select",
                           flags="c",
                           sql="SELECT x, z FROM {}".format(tmpout3),
                           stdout_=PIPE).outputs.stdout
            stats = stats.replace("\n", "|")[:-1].split("|")
            stats = (np.asarray([float(x) for x in stats],
                                dtype="float").reshape(len(stats) / 2, 2))
            rsme.append(np.sqrt(np.mean(np.diff(stats, axis=1)**2)))
            Module("g.remove", type="vector", pattern="cvtmp_*", flags="f")
        Module("g.remove", type="vector", pattern="cvbase_*", flags="f")
        return {
            'rsme_full': rsme_all,
            'rsme_cv_mean': np.asarray(rsme).mean(),
            'rsme_cv_std': np.asarray(rsme).std(),
            'rsme_cv': rsme
        }
    else:
        return {'rsme_full': rsme_all}
Ejemplo n.º 7
0
def idw_validation(vector,
                   column,
                   keep,
                   npoints=12,
                   power=2,
                   npartitions=10,
                   memory=2048):
    """Compute validation statistics (rsme) for idw extrapolation"""

    # Temporary map
    tmpmap = tmpname("cvbase_")
    Module("g.copy", vector=[vector, tmpmap])

    # Compute rsme over model with all callibration points
    tmpout = tmpname("cvtmp4_")
    Module("v.surf.idw",
           input=tmpmap,
           column=column,
           npoints=npoints,
           power=power,
           output=tmpout)
    Module("v.what.rast", map=tmpmap, raster=tmpout, column="idw")
    stats = Module("db.select",
                   flags="c",
                   sql="SELECT {},idw FROM {}".format(column, tmpmap),
                   stdout_=PIPE).outputs.stdout
    stats = stats.replace("\n", "|")[:-1].split("|")
    stats = (np.asarray([float(x) for x in stats],
                        dtype="float").reshape(len(stats) / 2, 2))
    rsme_all = np.sqrt(np.mean(np.diff(stats, axis=1)**2))
    if keep:
        Module("g.rename", raster=[tmpout, keep])
    else:
        Module("g.remove", type="raster", name=tmpout, flags="f")

    # Run n-fold crossvalidation
    if npartitions > 0:
        Module("v.kcv", map=tmpmap, npartitions=npartitions)
        rsme = []
        for i in range(1, npartitions + 1):
            tmppnt = tmpname("cvtmp2_")
            tmpspa = tmpname("cvtmp3_")
            tmpout = tmpname("cvtmp4_")
            Module("v.extract",
                   flags="r",
                   input=tmpmap,
                   output=tmppnt,
                   where="part={}".format(i))
            Module("v.extract",
                   input=tmpmap,
                   where="part={}".format(i),
                   output=tmpspa)
            Module("v.surf.idw",
                   input=tmppnt,
                   column=column,
                   npoints=npoints,
                   power=power,
                   output=tmpout)
            Module("v.what.rast", map=tmpspa, raster=tmpout, column="idw")
            stats = Module("db.select",
                           flags="c",
                           sql="SELECT {},idw FROM {}".format(column, tmpspa),
                           stdout_=PIPE).outputs.stdout
            stats = stats.replace("\n", "|")[:-1].split("|")
            stats = (np.asarray([float(x) for x in stats],
                                dtype="float").reshape(len(stats) / 2, 2))
            rsme.append(np.sqrt(np.mean(np.diff(stats, axis=1)**2)))
            Module("g.remove", type="all", pattern="cvtmp*", flags="f")
        Module("g.remove", type="vector", pattern="cvbase_*", flags="f")

    # Return output
    return {
        'rsme_full': rsme_all,
        'rsme_cv_mean': np.asarray(rsme).mean(),
        'rsme_cv_std': np.asarray(rsme).std(),
        'rsme_cv': rsme
    }