Skip to content

Commit f2a334a

Browse files
fdobadfdobad
and
fdobad
authored
Moknapsack2 (#27)
* raster.write_raster fixes: nodata, geotransform - gdal Only north-up non rotated geotransform supported * knapsack: plot fixes, config options, prints -> logs - knapsack aplot args show=False - unit testing init --------- Co-authored-by: fdobad <[email protected]>
1 parent e639535 commit f2a334a

16 files changed

+356
-118
lines changed

src/fire2a/knapsack.py

+229-111
Large diffs are not rendered by default.

src/fire2a/raster.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -408,8 +408,8 @@ def write_raster(
408408
outfile="output.tif",
409409
driver_name="GTiff",
410410
authid="EPSG:3857",
411-
geotransform=(0, 1, 0, 0, 0, 1),
412-
nodata=None,
411+
geotransform=(0, 1, 0, 0, 0, -1),
412+
nodata: int | None = None,
413413
feedback=None,
414414
logger=None, # logger default ?
415415
):
@@ -450,13 +450,15 @@ def write_raster(
450450
ds.SetGeoTransform(geotransform)
451451
ds.SetProjection(authid)
452452
band = ds.GetRasterBand(1)
453-
if nodata:
454-
if 0 != band.SetNoDataValue(nodata):
455-
fprint("Set NoData failed", level="warning", feedback=feedback, logger=logger)
456-
return False
457453
if 0 != band.WriteArray(data):
458-
fprint(f"WriteArray failed for Burn Probability {burn_prob}", level="warning", feedback=feedback, logger=logger)
454+
fprint("WriteArray failed", level="warning", feedback=feedback, logger=logger)
459455
return False
456+
if nodata and data[data == nodata].size > 0:
457+
band.SetNoDataValue(nodata)
458+
# TBD : always returns 1?
459+
# if 0 != band.SetNoDataValue(nodata):
460+
# fprint("Set NoData failed", level="warning", feedback=feedback, logger=logger)
461+
# return False
460462
ds.FlushCache()
461463
ds = None
462464
return True

tests/mok/OUT_LAYER.gpkg

104 KB
Binary file not shown.

tests/mok/config.toml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
["/home/fdo/source/fire/mok-tmp/v0.tif"]
2+
value_weight = 1.0
3+
4+
["/home/fdo/source/fire/mok-tmp/v1.tif"]
5+
value_weight = 1.25
6+
7+
["/home/fdo/source/fire/mok-tmp/v2.tif"]
8+
value_weight = 1.25
9+
10+
["/home/fdo/source/fire/mok-tmp/v3.tif"]
11+
value_weight = 1.0
12+
13+
["/home/fdo/source/fire/mok-tmp/w0.tif"]
14+
capacity_sense = "<="
15+
capacity_ratio = 0.25
16+
17+
["/home/fdo/source/fire/mok-tmp/w1.tif"]
18+
capacity_sense = "<="
19+
capacity_ratio = 0.25

tests/mok/instance.py

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!python3
2+
"""
3+
test instance for multi objective knapsack problem
4+
"""
5+
import sys
6+
7+
import numpy as np
8+
from fire2a.raster import write_raster
9+
from matplotlib import pyplot as plt
10+
11+
# arguments
12+
show, save, write = False, False, False
13+
if "show" in sys.argv:
14+
show = True
15+
if "save" in sys.argv:
16+
save = True
17+
if "write" in sys.argv:
18+
write = True
19+
20+
width = 80
21+
height = 60
22+
23+
x, y = np.meshgrid(np.arange(width), np.arange(height))
24+
25+
v = np.zeros((height, width, 4))
26+
v[:, :, 0] = np.sin(x * 2 * np.pi / width)
27+
v[:, :, 1] = -np.sin(x * 2 * np.pi / width)
28+
v[:, :, 2] = np.sin(y * 2 * np.pi / height)
29+
v[:, :, 3] = -np.sin(y * 2 * np.pi / height)
30+
31+
if show or save:
32+
fig, ax = plt.subplots(2, 2)
33+
fig.suptitle("values")
34+
for i, (j, k) in enumerate(np.indices((2, 2)).reshape(2, -1).T):
35+
ax[j, k].imshow(v[:, :, i])
36+
ax[j, k].set_title("v" + str(i))
37+
if show:
38+
plt.show()
39+
if save:
40+
plt.savefig("v.png")
41+
plt.close()
42+
43+
# all layers nodata
44+
v[1, 1, :] = -9999
45+
# one layer nodata
46+
v[0, 0, 0] = -9999
47+
48+
if write:
49+
for i in range(4):
50+
write_raster(v[:, :, i], "v" + str(i) + ".tif", nodata=-9999)
51+
52+
w = np.ones((height, width, 2))
53+
w[:, :, 0] += 1
54+
w[:, :, 1] += np.triu(w[:, :, 1])
55+
w[:, :, 1] += np.triu(w[:, :, 1], width // 3)
56+
w[:, :, 1] += np.triu(w[:, :, 1], width * 2 // 3)
57+
58+
if show or save:
59+
fig, ax = plt.subplots(1, 2)
60+
fig.suptitle("weights")
61+
for i in range(2):
62+
ax[i].imshow(w[:, :, i])
63+
ax[i].set_title("w" + str(i))
64+
if show:
65+
plt.show()
66+
if save:
67+
plt.savefig("w.png")
68+
plt.close()
69+
70+
# all layers nodata
71+
w[1, 1, :] = -9999
72+
# one layer nodata
73+
w[2, 2, 0] = -9999
74+
75+
if write:
76+
for i in range(2):
77+
write_raster(w[:, :, i], "w" + str(i) + ".tif", nodata=-9999)

tests/mok/log.html

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<span style="color:#777">QGIS version: 3.40.2-Bratislava</span><br/><span style="color:#777">QGIS code revision: 14826ca1e4a</span><br/><span style="color:#777">Qt version: 5.15.8</span><br/><span style="color:#777">Python version: 3.11.2</span><br/><span style="color:#777">GDAL version: 3.6.2</span><br/><span style="color:#777">GEOS version: 3.11.1-CAPI-1.17.1</span><br/><span style="color:#777">PROJ version: Rel. 9.1.1, December 1st, 2022</span><br/>Algorithm started at: 2025-01-06T00:39:16<br/>Input parameters:<br/><code>{ 'CUSTOM_OPTIONS_STRING' : '', 'DISPLAY_MODEL' : False, 'EXECUTABLE' : '', 'InputRasters' : ['/home/fdo/source/fire/mok-tmp/v0.tif','/home/fdo/source/fire/mok-tmp/v1.tif','/home/fdo/source/fire/mok-tmp/v2.tif','/home/fdo/source/fire/mok-tmp/v3.tif','/home/fdo/source/fire/mok-tmp/w0.tif','/home/fdo/source/fire/mok-tmp/w1.tif'], 'Matrix' : ['','1','','','','1.25','','','','1.25','','','','1','','','','','&lt;=','0.25','','','&lt;=','0.25'], 'NEOS_CUSTOM_OPTIONS_STRING' : '', 'NEOS_EMAIL' : '', 'NEOS_SOLVER' : 'cplex', 'OUT_LAYER' : 'TEMPORARY_OUTPUT', 'PLOTS' : True, 'SOLVER' : 'cplex: mipgap=0.005 timelimit=300' }</code><br/><br/>Solver unavailability:<br><br><br/><span style="color:#777">Input rasters names: ['v0', 'v1', 'v2', 'v3', 'w0', 'w1']<br></span><br/><span style="color:#777">/home/fdo/source/fire/mok-tmp/v0.tif : {'value_weight': 1.0}<br></span><br/><span style="color:#777">/home/fdo/source/fire/mok-tmp/v1.tif : {'value_weight': 1.25}<br></span><br/><span style="color:#777">/home/fdo/source/fire/mok-tmp/v2.tif : {'value_weight': 1.25}<br></span><br/><span style="color:#777">/home/fdo/source/fire/mok-tmp/v3.tif : {'value_weight': 1.0}<br></span><br/><span style="color:#777">/home/fdo/source/fire/mok-tmp/w0.tif : {'capacity_sense': '&lt;=', 'capacity_ratio': 0.25}<br></span><br/><span style="color:#777">/home/fdo/source/fire/mok-tmp/w1.tif : {'capacity_sense': '&lt;=', 'capacity_ratio': 0.25}<br></span><br/><span style="color:#b85a20;">fire2a-lib cli alternative:<br>python -m fire2a.knapsack -vv --authid EPSG:3857 --geotransform (0.0, 1.0, 0.0, 0.0, 0.0, -1.0) --plots --output_raster /tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/OUT_LAYER.gpkg /tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/tmptlh3t589.toml<br>Depending on the terminal the geotransform might need quotes &quot;(0,0,1,0,1)&quot; around it to be read correctly</span><br/><br/><span style="color:#777">options_string: mipgap=0.005 timelimit=300<br></span><br/>Solver object created 33%<br/><code style="color:#777"></code><br/><code style="color:#777"><br>Welcome to IBM(R) ILOG(R) CPLEX(R) Interactive Optimizer 22.1.1.0<br> with Simplex, Mixed Integer &amp; Barrier Optimizers<br>5725-A06 5725-A29 5724-Y48 5724-Y49 5724-Y54 5724-Y55 5655-Y21<br>Copyright IBM Corp. 1988, 2022. All Rights Reserved.<br>Type 'help' for a list of available commands.<br>Type 'help' followed by a command name for more<br>information on commands.<br></code><br/><code style="color:#777"><br>CPLEX&gt; Logfile 'cplex.log' closed.<br>Logfile '/tmp/tmp2799_93f.cplex.log' open.<br></code><br/><code style="color:#777">CPLEX&gt; New value for mixed integer optimality gap tolerance: 0.005<br></code><br/><code style="color:#777">CPLEX&gt; New value for time limit in seconds: 300<br></code><br/><code style="color:#777">CPLEX&gt; Problem '/tmp/tmpng6qoa01.pyomo.lp' read.<br>Read time = 0.01 sec. (0.26 ticks)<br></code><br/><code style="color:#777">CPLEX&gt; Problem name : /tmp/tmpng6qoa01.pyomo.lp<br>Objective sense : Maximize<br>Variables : 4799 [Binary: 4799]<br>Objective nonzeros : 4799<br>Linear constraints : 2 [Less: 2]<br> Nonzeros : 9597<br> RHS nonzeros : 2<br>Variables : Min LB: 0.000000 Max UB: 1.000000 <br>Objective nonzeros : Min : 2.000000 Max : 2.500000 <br>Linear constraints :<br> Nonzeros : Min : 1.000000 Max : 8.000000 <br> RHS nonzeros : Min : 2399.000 Max : 3077.500 <br></code><br/><code style="color:#777">CPLEX&gt; Version identifier: 22.1.1.0 | 2022-11-28 | 9160aff4d<br>CPXPARAM_TimeLimit 300<br>CPXPARAM_MIP_Tolerances_MIPGap 0.0050000000000000001<br>Found incumbent of value 0.000000 after 0.00 sec. (0.12 ticks)<br>Tried aggregator 1 time.<br>MIP Presolve eliminated 0 rows and 2358 columns.<br>MIP Presolve modified 3 coefficients.<br>Reduced MIP has 2 rows, 2441 columns, and 4881 nonzeros.<br>Reduced MIP has 1093 binaries, 1348 generals, 0 SOSs, and 0 indicators.<br>Presolve time = 0.01 sec. (4.64 ticks)<br></code><br/><code style="color:#777">Tried aggregator 1 time.<br>Detecting symmetries...<br>Reduced MIP has 2 rows, 2441 columns, and 4881 nonzeros.<br>Reduced MIP has 1093 binaries, 1348 generals, 0 SOSs, and 0 indicators.<br>Presolve time = 0.01 sec. (2.45 ticks)<br></code><br/><code style="color:#777">Probing time = 0.00 sec. (0.19 ticks)<br></code><br/><code style="color:#777">MIP emphasis: balance optimality and feasibility.<br>MIP search method: dynamic search.<br>Parallel mode: deterministic, using up to 4 threads.<br></code><br/><code style="color:#777">Root relaxation solution time = 0.01 sec. (1.72 ticks)<br></code><br/><code style="color:#777"><br> Nodes Cuts/<br> Node Left Objective IInf Best Integer Best Bound ItCnt Gap<br>* 0+ 0 0.0000 10797.7467 --- <br></code><br/><code style="color:#777">* 0 0 integral 0 2848.8583 2848.8583 6 0.00%<br>Elapsed time = 0.04 sec. (11.93 ticks, tree = 0.00 MB, solutions = 2)<br></code><br/><code style="color:#777"><br>Root node processing (before b&amp;c):<br> Real time = 0.04 sec. (12.11 ticks)<br>Parallel b&amp;c, 4 threads:<br> Real time = 0.00 sec. (0.00 ticks)<br> Sync time (average) = 0.00 sec.<br> Wait time (average) = 0.00 sec.<br> ------------<br>Total (root+branch&amp;cut) = 0.04 sec. (12.11 ticks)<br>Solution pool: 2 solutions saved.<br>MIP - Integer optimal solution: Objective = 2.8488582500e+03<br>Solution time = 0.04 sec. Iterations = 6 Nodes = 0<br>Deterministic time = 12.12 ticks (299.14 ticks/sec)<br></code><br/><code style="color:#777">CPLEX&gt; Incumbent solution written to file '/tmp/tmpm5v51crs.cplex.sol'.<br></code><br/><code style="color:#777">CPLEX&gt; </code><br/><code style="color:#777"></code><br/><code style="color:#777"></code><br/>Solver finished!<br/><code style="color:#777">Solver status=&lt;SolverStatus.ok: 'ok'&gt; and termination_condition=&lt;TerminationCondition.optimal: 'optimal'&gt;<br>good enough</code><br/>Results: {'OUTPUT': 'OUT_LAYER_cceff504_0761_479d_8c76_59259f7b19b8'}<br/><span style="color:#777">Showing layer /tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/OUT_LAYER.gpkg</span><br/><span style="color:#777">Plots:</span><br/><span style="color:#777">file:///tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/observations.png</span><br/><img src="/tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/observations.png"><br/><span style="color:#777">file:///tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/scaled.png</span><br/><img src="/tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/scaled.png"><br/><span style="color:#777">file:///tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/scaled_weighted.png</span><br/><img src="/tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/scaled_weighted.png"><br/><span style="color:#777">file:///tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/solution.png</span><br/><img src="/tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/solution.png"><br/>Results:<br/><code>&nbsp;&nbsp;OUT_LAYER: /tmp/processing_MoaEFQ/0ef1ab26b5dc4c0c9c463ca45fe8752c/OUT_LAYER.gpkg</code><br/>this output is written to: /tmp/algorithm_multirasterknapsack_log_3tlmt28n.html<br/>

tests/mok/mok.qgz

8.99 KB
Binary file not shown.

tests/mok/v.png

19.1 KB
Loading

tests/mok/v0.tif

19.1 KB
Binary file not shown.

tests/mok/v1.tif

19.1 KB
Binary file not shown.

tests/mok/v2.tif

19.1 KB
Binary file not shown.

tests/mok/v3.tif

19.1 KB
Binary file not shown.

tests/mok/w.png

17.2 KB
Loading

tests/mok/w0.tif

19.1 KB
Binary file not shown.

tests/mok/w1.tif

19.1 KB
Binary file not shown.

tests/mok/w1.tif.aux.xml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<PAMDataset>
2+
<PAMRasterBand band="1">
3+
<Histograms>
4+
<HistItem>
5+
<HistMin>0.9965000000000001</HistMin>
6+
<HistMax>8.003500000000001</HistMax>
7+
<BucketCount>1000</BucketCount>
8+
<IncludeOutOfRange>0</IncludeOutOfRange>
9+
<Approximate>0</Approximate>
10+
<HistCounts>1770|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|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|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|1544|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|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|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|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|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|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|1107|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|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|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|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|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|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|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|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|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|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|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|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|378</HistCounts>
11+
</HistItem>
12+
</Histograms>
13+
<Metadata>
14+
<MDI key="STATISTICS_MAXIMUM">8</MDI>
15+
<MDI key="STATISTICS_MEAN">2.565117732861</MDI>
16+
<MDI key="STATISTICS_MINIMUM">1</MDI>
17+
<MDI key="STATISTICS_STDDEV">1.9513461411422</MDI>
18+
<MDI key="STATISTICS_VALID_PERCENT">99.98</MDI>
19+
</Metadata>
20+
</PAMRasterBand>
21+
</PAMDataset>

0 commit comments

Comments
 (0)