+

AscRangeMask Guide

Overview

VELMA users often need to create a raster .asc file of ID or category values, based on the actual values of a different, pre-existing raster .asc map, to use as filter .asc or "jagged-array" .csv data when configuring simulation disturbances.
The best way to do this is with a GIS tool, but such tools and the training required to use them are not always readily avaiable.
AscRangeMask.py is a Python script that can generate a raster .asc file of id or category values, given a "source" raster .asc map, and a sequence of value ranges for that map.
It has significant limitations relative to using a GIS tool, but it can be useful as a quickly-available alternative.

Requirements

Limitations

Usage

Open a Windows Powershell or Command Prompt and type the following command:

py -3 AscRangeMask.py --help

Depending upon where the AscRangeMask.py script is located, you may need to include full or partial path info as part of its name.
The command above assumes it is being run in the directory where AscRangeMask.py is located.
Running the command above echoes AscRangeMask.py's help message to your console:

usage: AscRangeMask.py [-h] [--ranges RANGES [RANGES ...]] [--norangeValue NORANGEVALUE] [--outFilename OUTFILENAME]
                [--forceOverwrite] [--csvTargets CSVTARGETS [CSVTARGETS ...]] [--csvFilename CSVFILENAME]
                [--hideRanges] [--hideAsc] [--hideCsv]
                ascFilename
positional arguments:
  ascFilename           The .asc file to create a range mask for.
 
optional arguments:
  -h, --help            show this help message and exit
  --ranges RANGES [RANGES ...]
                        One or more range-triplets, format: id:minVal:maxVal.
  --norangeValue NORANGEVALUE
                        Assign this id to values outside any specified range.
  --outFilename OUTFILENAME
                        The .asc file to write the mask data to.
  --forceOverwrite      Overwrite preexisting file(s).
  --csvTargets CSVTARGETS [CSVTARGETS ...]
                        One or more id values.
  --csvFilename CSVFILENAME
                        The .csv file to write cells identified by csvTargets to.
  --hideRanges          Do NOT echo specified ranges to console.
  --hideAsc             Do NOT echo mask data asc map header and grid to console.
  --hideCsv             Do NOT echo target id and mask map locations to console.

Per the help message above:

  1. You must specify the source file (containing your original data values) as the first argument of the command line.
    The source file name is required, and must include whatever path information is necessary to find the file.

  2. You are not required to specify any value ranges, but if you do not, the output map will contain norange_value for every cell.
    To specify value ranges inlude the argument flag text --ranges on your command line, followed by whitespace-separated ranges.
    Each of the ranges is expressed as a colon-delmited triplet: id_number:min_value:max_value
    where:

  1. Values in the source map may fall outside any or all of the specified ranges. When they do, they are assigned the norange_value. You may specify what the norange_value by including the --norangeValue argument, followed by its (integer) value on the command line.
    If you do not specify a norange_value, it will be set to the integer (truncated) porition of the source map's nodata_value header value.
    Do not specify an integer for --norangeValue that is also specified as the id_number of one of the --ranges triplets.

  2. You may use the --outFilename argument to specify the path + name of the output file to write the ID/category map values to.
    If you do not, the ID/category map data is echoed to the console. This is convenient for checking behavior of the script against small source maps, but for "real" use, you will want to specify an output file. Include the --outFilename argument on your command line, followed by the path and file name for the output file.
    Note that AscRangeMask.py does not automatically append the .asc file extension to the filename you specify.

  3. If you specify an --outFilename file that already exists, AscRangeMask.py will echo a warning to the console and stop.
    You can force AscRangeMask.py to overwrite/replace the pre-existing file by adding the --forceOverwrite option to your command line.
    (Be sure you don't need the pre-existing file before you do this!)

  4. If you specify --csvTargets, the cell locations and x,y coordinates corresponding to the range ID values you specify are echoed to the console, and/or written to the file specified by the --csvFilename argument.
    When a --csvFilename is specified that already exists, AscRangeMask.py will echo a warning to the console and stop, unless, the --forceOverwrite option is part of the command line: both asc and csv file output forced-overwrite permission is detemined from this one command-line option.
    The --csvTargets argument expects to be followed by one or more integer range ID values.
    The target values must match range id_number values specified to the --ranges argument.
    For example:
    If a command line specifies --ranges 0:0.0:500.0 1:500.0:600.0 2:600:700, the --csvTargets argument may be followed by any combination of the integers 0, 1, 2, and only those integer values.
    Here is one valid possibility: --csvTargets 0 2
    The above possiblity would result in listing the cell locations and (x,y) coordinates for every cell in the original grid that falls into range 0 or 2, but not range 1.

  5. By default, AscRangeMask.py echoes a table of ranges data, followed by the mask map, followed by the csv targets (if specified) to console output. When the mask map and/or csv targets data is large, this can be very "noisy", as it will comprise many, many lines of closely-spaced numerical output to the console.
    The three --hide... command-line option switches suppress echoing the ranges table, asc, and csv data to console output.

How It Works

AscRangeMask.py loads the header and data of the .asc map file specified on the command line.
It collects the range triplets into a list, ordering them from lowest to highest min value, so that when the ranges of two IDs overlap, the ID of the lower min value is assigned.
It creates a new data map of ID values by iterating through the source map.

For each cell in the source map, the ID value is determined as follows:

  1. If the source map value is nodata_value, assign the integer (truncated) portion of the nodata_value as the ID value. (I.e. preseve nodata_value locations from the source map in the ID map.)
  2. If no range triplets are specified, assign the cell the norange_value.
    (The norange_value equals the integer (truncated) portion of the source map's nodata_value value if --norangeValue was left unspecified.)
  3. Iterate through the (sorted by min value) ranges, comparing the source map value with each range.
    Assign the cell the id of the first id:min:max triplet where (source map value />= min) and (source map value < max).
    (I.e. the source map value is in the range [min, max).)
  4. If the source map value falls within no range in the range sequence, assign it the norange_value. (Again, the norange_value may equal the integer (truncated) portion of the source map's nodata_value, depending upon whether a --norangeValue was specified or not.)

After creating a data array of ID values, AscRangemask.py writes the ID/catetory map (source header + mask ID data array) to the console, or, when an output file is specified via the --outFilename parameter, to the specified file.

When --csvTargets are specified, it uses the ID mask map to determine the list of cell locations to report, and echoes them to the console and/or to the file specified by -csvFilename

Examples

The following examples all assume a source map file named dem.asc.
Here are its contents:

ncols 24
nrows 24
xllcorner 558832.11763088
yllcorner 4896005.080683
cellsize 30.0
nodata_value -9999.0
438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0
438.0 438.0 462.0 491.0 499.0 505.0 507.0 530.0 534.0 536.0 562.0 563.0 564.0 569.0 588.0 584.0 589.0 611.0 611.0 614.0 623.0 648.0 661.0 438.0
438.0 438.0 486.0 507.0 516.0 520.0 525.0 553.0 557.0 559.0 584.0 585.0 588.0 591.0 610.0 607.0 610.0 631.0 631.0 631.0 632.0 661.0 668.0 438.0
438.0 438.0 499.0 521.0 530.0 539.0 547.0 571.0 577.0 582.0 604.0 606.0 606.0 607.0 631.0 632.0 629.0 629.0 652.0 653.0 657.0 676.0 679.0 438.0
438.0 438.0 510.0 532.0 544.0 556.0 556.0 574.0 583.0 590.0 598.0 619.0 623.0 626.0 644.0 649.0 650.0 651.0 668.0 673.0 673.0 683.0 683.0 438.0
438.0 438.0 506.0 518.0 537.0 553.0 566.0 579.0 589.0 599.0 610.0 626.0 634.0 639.0 649.0 659.0 663.0 665.0 669.0 676.0 680.0 686.0 686.0 438.0
438.0 438.0 511.0 524.0 541.0 559.0 569.0 582.0 593.0 604.0 617.0 623.0 631.0 642.0 643.0 650.0 650.0 652.0 648.0 664.0 676.0 683.0 681.0 438.0
438.0 438.0 513.0 525.0 543.0 561.0 571.0 583.0 593.0 593.0 603.0 605.0 613.0 625.0 636.0 626.0 628.0 637.0 653.0 669.0 678.0 683.0 665.0 438.0
438.0 438.0 514.0 514.0 528.0 543.0 560.0 571.0 581.0 590.0 597.0 591.0 599.0 611.0 620.0 605.0 616.0 634.0 661.0 671.0 676.0 675.0 642.0 438.0
438.0 438.0 502.0 515.0 528.0 542.0 558.0 569.0 573.0 581.0 586.0 578.0 585.0 591.0 598.0 601.0 620.0 643.0 663.0 663.0 668.0 667.0 635.0 438.0
438.0 438.0 500.0 514.0 524.0 537.0 552.0 563.0 559.0 566.0 572.0 556.0 562.0 562.0 572.0 595.0 613.0 630.0 655.0 661.0 662.0 654.0 615.0 438.0
438.0 438.0 498.0 512.0 519.0 528.0 528.0 539.0 532.0 539.0 546.0 533.0 539.0 555.0 575.0 605.0 622.0 640.0 655.0 657.0 653.0 634.0 598.0 438.0
438.0 438.0 477.0 494.0 508.0 513.0 520.0 526.0 517.0 521.0 525.0 533.0 552.0 568.0 587.0 612.0 629.0 647.0 655.0 648.0 632.0 613.0 584.0 438.0
438.0 438.0 475.0 489.0 503.0 507.0 512.0 514.0 503.0 506.0 521.0 535.0 567.0 580.0 597.0 617.0 617.0 636.0 650.0 644.0 631.0 611.0 578.0 438.0
438.0 438.0 470.0 482.0 496.0 492.0 497.0 500.0 493.0 514.0 514.0 536.0 566.0 580.0 593.0 614.0 625.0 640.0 648.0 624.0 608.0 591.0 578.0 438.0
438.0 438.0 464.0 464.0 473.0 468.0 475.0 484.0 501.0 516.0 533.0 550.0 578.0 594.0 604.0 614.0 630.0 635.0 635.0 600.0 583.0 571.0 560.0 438.0
438.0 438.0 452.0 458.0 463.0 468.0 481.0 491.0 501.0 535.0 547.0 562.0 588.0 603.0 615.0 624.0 629.0 623.0 612.0 578.0 578.0 565.0 552.0 438.0
438.0 438.0 449.0 454.0 461.0 483.0 495.0 507.0 520.0 548.0 560.0 574.0 600.0 600.0 614.0 626.0 628.0 618.0 606.0 577.0 566.0 550.0 536.0 438.0
438.0 438.0 449.0 455.0 468.0 495.0 506.0 506.0 520.0 545.0 559.0 572.0 597.0 610.0 626.0 634.0 615.0 603.0 589.0 577.0 550.0 536.0 524.0 438.0
438.0 438.0 446.0 452.0 462.0 488.0 501.0 513.0 527.0 551.0 567.0 583.0 597.0 618.0 633.0 630.0 601.0 587.0 573.0 562.0 534.0 524.0 514.0 438.0
438.0 438.0 448.0 455.0 467.0 488.0 505.0 517.0 532.0 556.0 573.0 590.0 604.0 621.0 627.0 615.0 587.0 587.0 572.0 555.0 532.0 522.0 509.0 438.0
438.0 438.0 450.0 459.0 472.0 491.0 509.0 521.0 537.0 563.0 563.0 582.0 598.0 612.0 618.0 614.0 588.0 575.0 558.0 541.0 526.0 515.0 501.0 438.0
438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0
438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0 438.0

The values within dem.asc range from 438.0 to 686.0.

The examples also assume that the AscRangeMask.py script file, the dem.asc source map file, and any output files all exist in the currently directory.
In practice, this will not typically be the case, but the only adaptation is adding the appropriate paths to the appropriate file names.

Typical Usage Example

Divide dem.asc into 3 categories:

Value Range Category ID
up to 500 0
500 to 600 1
600 or more 2

We know that dem.asc's minimum value is 438.0, so we can set the min value of the lowest range to any at or below 438.0.
We'll use 0.0 for convenience. Likewise, we know that dem.asc's maximum value is 686.0. Any value higher than that will fulfill the "or more" of the highest range.

The command line . . .

py -3 AscRangeMask.py dem.asc --ranges 0:0.0:500.0 1:500.0:600.0 2:600:700

produces the following output on the console . . .

# RANGE TABLE (Ordered: lowest to highest min value.)
ID   |   Min |   Max | Occurences | Fraction
---- | ----- | ----- | ---------- | --------
0    |   0.0 | 500.0 |        184 |    0.319
1    | 500.0 | 600.0 |        225 |    0.391
2    | 600.0 | 700.0 |        167 |    0.290
norange_value=-9999  occurs=0 fraction=0.000
nodata_value=-9999.0
# ASC MASK MAP
ncols 24
nrows 24
xllcorner 558832.11763088
yllcorner 4896005.080683
cellsize 30.0
nodata_value -9999.0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 0
0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 1 0
0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 1 0
0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 1 0
0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 2 2 2 2 2 2 1 1 0
0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 0
0 0 0 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 0
0 0 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 0
0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 0
0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 0
0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 1 0
0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

The "# RANGE TABLE" reports the --ranges specified on the command line, along with the number of cells in the source asc file that fall within each range category ("Occurences"), and what "Fraction" of the total cells in the asc grid that occurence count represents.
The fractions in the table may not sum to 1.0, due to either floating-point rounding effects, or a non-zero occurence count of norange cells (reported below the table, instead of within it).

Omitting Cells Example

Find cells with a specific value in dem.asc, ignoring all other cells:

The command line . . .

py -3 AscRangeMask.py dem.asc --ranges 1:438.0:438.0

produces the following output on the console . . .

# RANGE TABLE (Ordered: lowest to highest min value.)
ID   |   Min |   Max | Occurences | Fraction
---- | ----- | ----- | ---------- | --------
1    | 438.0 | 438.0 |        135 |    0.234
norange_value=-9999  occurs=441 fraction=0.766
nodata_value=-9999.0
# ASC MASK MAP
ncols 24
nrows 24
xllcorner 558832.11763088
yllcorner 4896005.080683
cellsize 30.0
nodata_value -9999.0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

Any cells != 428.0 in dem.asc are represented by the integer portion of the nodata_value.

As a variation of the above, let's set the --norangeValue.
The command line . . .

py -3 AscRangeMask.py dem.asc --ranges 1:438.0:438.0 --norangeValue 0

produces the following output on the console . . .

# RANGE TABLE (Ordered: lowest to highest min value.)
ID   |   Min |   Max | Occurences | Fraction
---- | ----- | ----- | ---------- | --------
1    | 438.0 | 438.0 |        135 |    0.234
norange_value=0  occurs=441 fraction=0.766
nodata_value=-9999.0
# ASC MASK MAP
ncols 24
nrows 24
xllcorner 558832.11763088
yllcorner 4896005.080683
cellsize 30.0
nodata_value -9999.0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

The cells identified as in-range have not changed, but the cells that are not in-range ("norange" cells) now are identified by the specified norange_value of 0.

Capturing Output In A File Example

Re-running our Typical Usage Example with the --outFilename argument, and hiding console output of mask data.

py -3 AscRangeMask.py dem.asc --ranges 0:0.0:500.0 1:500.0:600.0 2:600:700 --outFilename mask.asc --hideAsc

produces the following output . . .

# RANGE TABLE (Ordered: lowest to highest min value.)
ID   |   Min |   Max | Occurences | Fraction
---- | ----- | ----- | ---------- | --------
0    |   0.0 | 500.0 |        184 |    0.319
1    | 500.0 | 600.0 |        225 |    0.391
2    | 600.0 | 700.0 |        167 |    0.290
norange_value=-9999  occurs=0 fraction=0.000
nodata_value=-9999.0
DONE: wrote mask to file "mask.asc"

Note:

Here are the contents of the mask.asc file:

ncols 24
nrows 24
xllcorner 558832.11763088
yllcorner 4896005.080683
cellsize 30.0
nodata_value -9999.0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 0
0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 0
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 1 0
0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 1 0
0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 1 0
0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 2 2 2 2 2 2 1 1 0
0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 0
0 0 0 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 0
0 0 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 0
0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 0
0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 0
0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 1 0
0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Targeting Specific Cells by Their Range IDs Example

First, let's see if we can identify a small group of cells at the upper end of the source file's values range.
The following command line sets some ranges, and suppresses console output other than the range table report.

py -3 AscRangeMask.py dem.asc --ranges 0:0:450 1:450:550 2:550:650 3:650:700 4:700:900 --hideAsc

Here are the results:

# RANGE TABLE (Ordered: lowest to highest min value.)
ID   |   Min |   Max | Occurences | Fraction
---- | ----- | ----- | ---------- | --------
0    |   0.0 | 450.0 |        139 |    0.241
1    | 450.0 | 550.0 |        147 |    0.255
2    | 550.0 | 650.0 |        238 |    0.413
3    | 650.0 | 700.0 |         52 |    0.090
4    | 700.0 | 900.0 |          0 |    0.000
norange_value=-9999  occurs=0 fraction=0.000
nodata_value=-9999.0

Based on the occurence numbers above, let's see if there are any cells between 675.0 and 700.0.

py -3 AscRangeMask.py dem.asc --ranges 0:0:450 1:450:550 2:550:650 3:650:675 4:675:900 --hideAsc

Here are the results with the slightly-modified upper range:

# RANGE TABLE (Ordered: lowest to highest min value.)
ID   |   Min |   Max | Occurences | Fraction
---- | ----- | ----- | ---------- | --------
0    |   0.0 | 450.0 |        139 |    0.241
1    | 450.0 | 550.0 |        147 |    0.255
2    | 550.0 | 650.0 |        238 |    0.413
3    | 650.0 | 675.0 |         37 |    0.064
4    | 675.0 | 900.0 |         15 |    0.026
norange_value=-9999  occurs=0 fraction=0.000
nodata_value=-9999.0

To report the locations of the 15 cells whose source map values are >= 657.0, we add the --csvTargets argument to the command line, and run again:

py -3 AscRangeMask.py dem.asc --ranges 0:0:450 1:450:550 2:550:650 3:650:675 4:675:900 --csvTargets 4 --hideAsc

A comma-separated list of the cells now follows the range table in the console output.

# RANGE TABLE (Ordered: lowest to highest min value.)
ID   |   Min |   Max | Occurences | Fraction
---- | ----- | ----- | ---------- | --------
0    |   0.0 | 450.0 |        139 |    0.241
1    | 450.0 | 550.0 |        147 |    0.255
2    | 550.0 | 650.0 |        238 |    0.413
3    | 650.0 | 675.0 |         37 |    0.064
4    | 675.0 | 900.0 |         15 |    0.026
norange_value=-9999  occurs=0 fraction=0.000
nodata_value=-9999.0
# CSV TARGET IDs
ID,icell,xcell,ycell
4,93,21,3
4,94,22,3
4,117,21,4
4,118,22,4
4,139,19,5
4,140,20,5
4,141,21,5
4,142,22,5
4,164,20,6
4,165,21,6
4,166,22,6
4,188,20,7
4,189,21,7
4,212,20,8
4,213,21,8

To save that list of cells to a file, we could add the --csvFilename argument, followed by the name of the file to write.
(The first row of the file would be the ID,icell,xcell,ycell console text. The # CSV TARGET IDs separator is console-only text that is never written to the .csv file.)