From f2002d4d7df2ec520c197bc6eeadc277284988a2 Mon Sep 17 00:00:00 2001
From: Hans Roelofsen <hans.roelofsen@wur.nl>
Date: Thu, 2 Feb 2023 10:56:38 +0100
Subject: [PATCH] mmmm

---
 COMBINE.py => src/COMBINE.py                  |  39 ++++---
 .../attribute_table.cpython-310.pyc           | Bin 0 -> 1512 bytes
 src/__pycache__/combinations.cpython-310.pyc  | Bin 0 -> 1963 bytes
 .../source_rasters.cpython-310.pyc            | Bin 0 -> 5275 bytes
 src/__pycache__/target_raster.cpython-310.pyc | Bin 0 -> 3652 bytes
 src/__pycache__/windows.cpython-310.pyc       | Bin 0 -> 2540 bytes
 attribute_table.py => src/attribute_table.py  |   5 +-
 combinations.py => src/combinations.py        |   9 +-
 source_rasters.py => src/source_rasters.py    |  64 +++++++++--
 target_raster.py => src/target_raster.py      |  36 +++----
 src/windows.py                                | 100 ++++++++++++++++++
 windows.py                                    |  77 --------------
 12 files changed, 206 insertions(+), 124 deletions(-)
 rename COMBINE.py => src/COMBINE.py (70%)
 create mode 100644 src/__pycache__/attribute_table.cpython-310.pyc
 create mode 100644 src/__pycache__/combinations.cpython-310.pyc
 create mode 100644 src/__pycache__/source_rasters.cpython-310.pyc
 create mode 100644 src/__pycache__/target_raster.cpython-310.pyc
 create mode 100644 src/__pycache__/windows.cpython-310.pyc
 rename attribute_table.py => src/attribute_table.py (88%)
 rename combinations.py => src/combinations.py (76%)
 rename source_rasters.py => src/source_rasters.py (69%)
 rename target_raster.py => src/target_raster.py (86%)
 create mode 100644 src/windows.py
 delete mode 100644 windows.py

diff --git a/COMBINE.py b/src/COMBINE.py
similarity index 70%
rename from COMBINE.py
rename to src/COMBINE.py
index fff2493..d188f82 100644
--- a/COMBINE.py
+++ b/src/COMBINE.py
@@ -18,11 +18,10 @@ except ModuleNotFoundError:
 with Flow("COMBINE") as COMBINE:
 
     destination = Parameter("destination")
-    source_rasters = Parameter('sources')
-    testing = Parameter('testing')
+    source_rasters = Parameter("sources")
+    testing = Parameter("testing")
 
     source_rasters = get_source_rasters(source_rasters)
-
     rw_windows = get_rw_windows(source_rasters=source_rasters, sample=testing)
 
     combinations_per_window = get_combinations.map(rw_windows, unmapped(source_rasters))
@@ -43,12 +42,14 @@ with Flow("COMBINE") as COMBINE:
     max_value = get_max_value(combination_dict)
     max_value.set_dependencies(upstream_tasks=[attribute_table_to_file])
 
-    target_raster_written = write_target_raster_chunk.map(rw_windows,
-                                                          unmapped(destination),
-                                                          unmapped(max_value),
-                                                          unmapped(combination_dict),
-                                                          unmapped(source_rasters))
-    target_raster_written.set_dependencies(upstream_tasks=[combination_dict])
+    target_raster_written = write_target_raster_chunk.map(
+        rw_windows,
+        unmapped(destination),
+        unmapped(max_value),
+        unmapped(combination_dict),
+        unmapped(source_rasters),
+    )
+    target_raster_written.set_dependencies(upstream_tasks=[combination_dict, max_value])
 
 
 if __name__ == "__main__":
@@ -61,7 +62,7 @@ if __name__ == "__main__":
         Path to destination *.tif file
     source_raster01: Path to first source raster
     source_raster02: Path to second source raster
-    ...: path to subsequent source  rasters 
+    ...: path to subsequent source  rasters
 
     Returns
     -------
@@ -69,15 +70,21 @@ if __name__ == "__main__":
 
     import argparse
 
-    parser = argparse.ArgumentParser(prog='Open Source COMBINE alternative. By: Hans Roelofsen')
+    parser = argparse.ArgumentParser(
+        prog="Open Source COMBINE alternative. By: Hans Roelofsen"
+    )
     parser.add_argument("destination", type=str, help="path to destination *.tif file")
-    parser.add_argument("sources", type=str, help="path to destination source files", nargs='+')
-    parser.add_argument('--test', action='store_true', help='test run with 20 windows')
+    parser.add_argument(
+        "sources", type=str, help="path to destination source files", nargs="+"
+    )
+    parser.add_argument("--test", action="store_true", help="test run with 20 windows")
     args = parser.parse_args()
 
     print("\n\nStarting COMBINE\n\n")
 
     COMBINE.executor = LocalDaskExecutor()
-    COMBINE.run(parameters=dict(destination=args.destination,
-                                sources=args.sources,
-                                testing=args.test))
+    COMBINE.run(
+        parameters=dict(
+            destination=args.destination, sources=args.sources, testing=args.test
+        )
+    )
diff --git a/src/__pycache__/attribute_table.cpython-310.pyc b/src/__pycache__/attribute_table.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8c807626c53ce94ab3f359a253bdd861a6eb6365
GIT binary patch
literal 1512
zcmd1j<>g{vU|@Jxb36GVGXuk85C<7^FfcGUFfcF_H!v_Tq%fo~<}gGtrZA*1<uK(k
zM=>)(#8{$OsyI>@QkZjCbJ?QU7#YGD^7vU8QrRn285uwjEXM(ni)6@SEN4h%PGL#q
zOkquBOJPgpN@Gi5PvK}`X=aS#hRSfJ@}#k(aHVjAMR`*ggBdh=UV_}_r^$GWr6jR9
zTa)n?Z*YETQF3ZfVsS}oQSmLV<ow*E%=nbd<dR!_#bBxUBB&g9N@{UQW?o`RW`15W
zGsqw)W?^7pU}Iola0dA^hk=2igdvMDiz$UMg{g(1hG7BoLIxLxX2uj|FrP7t1<Yds
z^B5MeLS<QdnQNJAn6ubY*izVg85tRBn6ubRII=hwaMds^WK7|ZWSGs6!a0{Ig$?AZ
zUQpQa1T$#zR>g90DJUo?SQR7|CFUw1d|-tvjOrN_DI|YE#fwr)N{jL!oMc9*H$fB=
z0|Nud>%j~R44(xU7#PwSY8YZ!Y8h)7Co&Z>1v9K<C;~;fCetk@J%d|}6<{8i_+{v9
z6_Z#{P#jZGl%Ex!oS%{!19od(YEevaQF2UTNl8&=QfWzQd`V(bPO4r(<t;9ooXp~q
z<ow(MI|-1DAnOGfsx)#Fvs2^I)!XFcCnx3<+vy=RVYr>0fq?<!_F@&7+xco4LD98<
z2~0BAFfL?V$e6+)$pG<>CSwuE|C%hfnDUEnu@oehWZdE?F38C&Nv$Zk#gUX)oSK)I
zo2toF#L2+G5XDtolnhNUU{6B`ZUzR1A|3_?21!r~0fi460~3?jf42V^4ul165y+(w
z-5~W)^KUVhA;gN{#>#@s=Vf4E&}6>Fl9E`Gc#AzbKc_S|ulN>gW?o8aMTjQjE!NbE
z<kTFnZ>m`Il8ei3v4$n)l!BZt%D}*IiyN#mJ|{6LHOEhr`xa9{$}LWp#F9j}qQu<P
zTRdq+`ML2$smb|8DaE%~vQsOIZ*fBt6)2K!v6X>LE55~3k{_R(lUb0IpIDS~iw(pp
zE-T^#IguYkfKrVnOA#p36tRK?Kw0M&b4g+nn%8cLV2fsur;EivIgUqwk&TgsiRGUF
z3)?Rq4i-iUMy~%wN+7?mK@u=Z=z^jVlzzau6cnZ<3^feRpi+UcN(+Auf|v%$4w{U&
zm~&F|G#Md202u^vH^^bPc+*o$;&T%#;=zHT3W{!!ogC~%AhssoEw+Nhyp+V^B2Y@W
z#a>X9nwFYeQUp>12_kTafD*wiVc-0e(wtPk{1UhP(!3PcqN4nwTSCP}$$HRGhm}h#
z;L?h@xTFZ;dFIT#60mg;ccHnE!zLGOt{o^mz}bL<frpWUk%>uwk%v)$k?B7Z3lk#~
Nhz4Vx|4fn+i~zCgXoLU&

literal 0
HcmV?d00001

diff --git a/src/__pycache__/combinations.cpython-310.pyc b/src/__pycache__/combinations.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..52b14f944f89c2122448097f296b18674c7a2626
GIT binary patch
literal 1963
zcmd1j<>g{vU|=w-y`8Mc#=!6x#6iX!3=9ko3=9m#YZw?9QW#Pga~Pr+!8B78a|%NW
zQw~cmYZNOZM2;<rErlV4IfpHmJ&K)?p^7hsA%!J}BbPIZ6Rd(Yhbxymikp!koFPw?
zg&~!v(wdP01i|Wfk<{@))I~DnF_tr=vZt`6a;C7Sa;I>l@~5$-aHepzurxD938b>8
zaHk5UaHI;Qv83>%@Pb8!Qy7C8H2GeF{Nbm`c#ADOGcP5-T$Aw@OG#pJwkG2(Ug!MW
zq|CfjxCC!-erZv1YEWWvNorB?E$*V!#FY4Qu(n%##bCMkBB&%=QEEwPQC>0=$b2Yf
zWnf?c1tc>ls2Ug;7)ltj7#A?5FfL@QWvXFXz?{O=!H~r=n<0g{gCUD`Hp5(&g^Y|0
z?F?y*DJ&_hEgUtBS!^y0&5X6oCF~^}C7d<PeGJWv&5X4yVBKsW-6`y|SyDJkxE64i
za4q1eVOhwykP&852SXNb4ND4VFC!yE3Rf_LCU?~%E(HYz1^3hvh2qo_h5R&y#GD+3
zWU$8*OEUBGiWM^R6cQD3GK(RyMMa5~#R?^fMd_&}sVNGHB?^fO#hH2OIjIVu;LtBG
z$}CA$fCP#n*leqU#G=Gpuq-sNtP~QVDvI?`!dM|cDJwO(q!?KrYPed#T~d%(l2NQs
zlCJ;_afSRmg|y6^REXXpaOhisIk(ty^3&5(i>lPzGV@Y0^U@Vc^D+xdQ!%^=akWAf
zheCcS*tf}y(3k^JpqON1U|<ji#hw}i14BAP4MQw{En^A80>&D~g^XEDDGVJ9S<ESn
zy-W*O7BWm^Dr5>~&}4cEG6j^vAm(eb-eNAw%)iBwUyz!2iv<*FQCvlt`Ov_*#h#Xv
zSW=Rjr^$4SNzWjP7bO5zG8Tc{u#(}Ip0ia<VnIQ1OhHk8R(x`PN@@%w+ER;Rii?t=
z97r7M6;$5hvH`_ma(-@sodU=QpghaQz{Di+pY4B@N_uKZJVZNGhfPj?a$-)gogPA4
zm3U5md1`TqLRn%?X(}jPKs=-n#cW_;QpIGYpvf4;RGRFk$#;vrpeQvhHM!&#dvbnW
zNoqyOE#~ypl3Og9d1?8#nDUBlv6keQB<9@WhWZZVwp+}_ASDoHRc660ro4h%%(<C)
zw^$QF$u3H~IJG1m5_c$$)no++N)bB)149uf0|Ub?Hn4``C}AwBi-bVR1VIESDsKs(
z`<)*YJQ55H3_Lt6j6#eo|G8LLnArXau(B}9F|zy@U@lSy*}(&fIcTI6qofp2{s!fB
zXOKZA;C$Z9P|H}u;KC5gS<6(zxPY;SX#vwhhJ}o^jD@Tzj44bl3?<Apj48}1EWJ#i
z93IS|$?At;C<_AvLomotF$M;POi=P;k723>7alc?lflUi;yaKRHJOV9K<;GBi(&;w
zEkddY>~Suel+5H3aEdSl8460^VhmN9xry1S$l)6gQl^JU5FjpCR}rW%(`3BGT3nJ?
zRHDgJBm=UKwKOj?KQBrg6s%Z+{}yLzUTJP>QDRA|CUcPr0|P^pKw?e~vW3Nv=mdEJ
z;%2aOMX|a|2jp^aT4v&46krr%EYf0NV9*q~#hO=|TTodf4{{O*q>RYSFX91l1z=n~
zNCGY{0(rei6qF=Dad(RyCJqX4NU{RO=PhC1{FKt1RKNTZxBSw)6xX7n{Gwaj#YM?5
zgKi0dIM6f=v85OsD&QnjBnz^g1r&Z@S3*38=1mTpT(Bi}pi-k4<UI}s4n`hE5N2ZH
iVH9BGVFZy(|Cm^r7?~KE{xdN#{bOS0`O73D!3Y2j{}xvO

literal 0
HcmV?d00001

diff --git a/src/__pycache__/source_rasters.cpython-310.pyc b/src/__pycache__/source_rasters.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b9fc20a4187b78cd9bfa0950ab9e5c99ed5a8af3
GIT binary patch
literal 5275
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

literal 0
HcmV?d00001

diff --git a/src/__pycache__/target_raster.cpython-310.pyc b/src/__pycache__/target_raster.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..121ad595526dde3d97fe371f7ef30a0a5985baa8
GIT binary patch
literal 3652
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

literal 0
HcmV?d00001

diff --git a/src/__pycache__/windows.cpython-310.pyc b/src/__pycache__/windows.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e8b7c66308c11ac29be546a44a6ee04416ca9f5b
GIT binary patch
literal 2540
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
TGckjLiRBLyByf<*Ac5Zi{*Z{*

literal 0
HcmV?d00001

diff --git a/attribute_table.py b/src/attribute_table.py
similarity index 88%
rename from attribute_table.py
rename to src/attribute_table.py
index 4723dcb..d85d74e 100644
--- a/attribute_table.py
+++ b/src/attribute_table.py
@@ -29,7 +29,9 @@ def make_attribute_table(
         index=[v for v in combi_dict.values()],
     )
     tab.to_clipboard(excel=True)
-    tab.to_csv(f"{os.path.splitext(destination)[0]}.csv", index=True, index_label="Value")
+    tab.to_csv(
+        f"{os.path.splitext(destination)[0]}.csv", index=True, index_label="Value"
+    )
 
 
 @task
@@ -40,4 +42,3 @@ def get_max_value(combi_dict: dict) -> int:
     :return:
     """
     return len(combi_dict)
-
diff --git a/combinations.py b/src/combinations.py
similarity index 76%
rename from combinations.py
rename to src/combinations.py
index eefd3b0..7ccdde8 100644
--- a/combinations.py
+++ b/src/combinations.py
@@ -11,6 +11,7 @@ except ModuleNotFoundError:
     from src.windows import CombineWindow
     from src.source_rasters import SourceRasters
 
+
 @task
 def get_combinations(
     read_window: CombineWindow,
@@ -25,7 +26,7 @@ def get_combinations(
 
     logger = prefect.context.get("logger")
     logger.info(
-        f"Finding unique combinations in window {read_window.nr:004}"
+        f"Finding unique combinations in window {read_window.nr} out of {read_window.total}"
     )
 
     arrays = [
@@ -34,7 +35,9 @@ def get_combinations(
     ]
 
     unique_combinations = set(list(zip(*arrays)))
-    logger.info(f'lowest value in window {read_window.nr:004}: {np.min(np.array(unique_combinations))}')
+    logger.info(
+        f"lowest value in window {read_window.nr:004}: {np.min(np.array(unique_combinations))}"
+    )
     read_window.set_unique_combinations(uc=unique_combinations)
 
 
@@ -46,5 +49,3 @@ def make_combination_dict(read_windows: list) -> dict:
     return {combi: n for n, combi in enumerate(all_combinations, start=1)}
 
 
-src = r'w:\PROJECTS\Nvk_bdb\b_HDB\b_scenarios\2_regionaal\brondata\Regionaal_Geworteld_Subsector_rel_Y2050\25m\Regionaal_Geworteld_Subsector_rel_Y2050.tif'
-arr = rio.open(src, window=Window(0, 0, 100, 150)).read(1).flatten()
\ No newline at end of file
diff --git a/source_rasters.py b/src/source_rasters.py
similarity index 69%
rename from source_rasters.py
rename to src/source_rasters.py
index 27371c5..4526d55 100644
--- a/source_rasters.py
+++ b/src/source_rasters.py
@@ -7,14 +7,16 @@ from abc import ABC, abstractmethod
 from prefect.engine import signals
 import pandas as pd
 
-class SourceRasters:
 
+class SourceRasters:
     def __init__(self, source_list: list):
 
         self.source_list = [s for s in source_list]
-        self.procedures = [VerifyAsGeospatialRaster(source_list=self.source_list),
-                           VerifyMatchingBounds(source_list=self.source_list)]
-        self.geospatial_profile = getattr(rio.open(self.source_list[0]), 'profile')
+        self.procedures = [
+            VerifyAsGeospatialRaster(source_list=self.source_list),
+            VerifyMatchingBounds(source_list=self.source_list),
+            VerifyMatchingResolution(source_list=self.source_list),
+        ]
 
     def verify_input(self):
         for procedure in self.procedures:
@@ -39,7 +41,7 @@ class VerificationProcedure(ABC):
         pass
 
 
-class VerifyAsGeospatialRaster(ABC):
+class VerifyAsGeospatialRaster(VerificationProcedure):
     def __init__(self, source_list):
         self.rasters = source_list
         self.status = True
@@ -53,10 +55,10 @@ class VerifyAsGeospatialRaster(ABC):
                 logger.info(message)
             else:
                 logger.error(message)
-                self.status=False
+                self.status = False
 
 
-class VerifyMatchingBounds(ABC):
+class VerifyMatchingBounds(VerificationProcedure):
     def __init__(self, source_list):
         self.rasters = source_list
         self.status = True
@@ -72,6 +74,27 @@ class VerifyMatchingBounds(ABC):
                 self.status = False
 
 
+class VerifyMatchingResolution(VerificationProcedure):
+
+    def __init__(self, source_list):
+        self.rasters = source_list
+        self.status = True
+
+    def execute(self):
+        logger = prefect.context.get("logger")
+
+        reference_resolution = getattr(getattr(rio.open(self.rasters[0]), 'transform'), 'a')
+        resolutions = []
+        messages = []
+        for raster in self.rasters:
+            has_resolution, msg = raster_has_resolution(raster, reference_resolution)
+            resolutions.append(has_resolution)
+            messages.append(msg)
+
+        if not all(resolutions):
+            logger.error('Rasters have unequal resolutions')
+            self.status = False
+
 def is_geospatial_raster(file_path: str, msg=False) -> (bool, str):
     """
     Is a file a gdal compatible geospatial raster?
@@ -161,6 +184,33 @@ def rasters_have_identical_bounds(rasters: list) -> (bool, str):
     return out, msg
 
 
+def raster_has_resolution(file_path: str, target_resolution) -> (bool, str):
+    """
+    Check if a raster has target resolution
+    Parameters
+    ----------
+    file_path: target file path
+    target_resolution: expected resolution of the raster
+
+    Returns
+    -------
+
+    """
+
+    if is_geospatial_raster(file_path):
+        raster_resolution = getattr(rio.open(file_path), "res")[0]
+        has_target_resolution = raster_resolution == target_resolution
+        if has_target_resolution:
+            out = True
+            msg = f"{os.path.basename(file_path)} has target resolution."
+        else:
+            out = False
+            msg = f"{os.path.basename(file_path)} resolution {raster_resolution}m does not meet target resolution {target_resolution}."
+        return out, msg
+    else:
+        return False, f"{os.path.basename} is not a geospatial raster"
+
+
 @task
 def get_source_rasters(source_list: list) -> SourceRasters:
 
diff --git a/target_raster.py b/src/target_raster.py
similarity index 86%
rename from target_raster.py
rename to src/target_raster.py
index 2c37b26..7431809 100644
--- a/target_raster.py
+++ b/src/target_raster.py
@@ -12,31 +12,30 @@ except ModuleNotFoundError:
     from src.source_rasters import SourceRasters
     from src.windows import CombineWindow
 
+
 @task
 def write_target_raster_chunk(
-        rw_window: CombineWindow,
-        destination: str,
-        max_value: int,
-        combi_dict: dict,
-        source_rasters: SourceRasters
+    rw_window: CombineWindow,
+    destination: str,
+    max_value: int,
+    combi_dict: dict,
+    source_rasters: SourceRasters,
 ):
-    """
-    Write target raster for a single RW Window
-    """
+
 
     logger = prefect.context.get("logger")
 
     with rio.open(
-            destination,
-            "w",
-            driver="GTiff",
-            width=rw_window.rio_window.width,
-            height=rw_window.rio_window.height,
-            count=1,
-            dtype=rio.dtypes.get_minimum_dtype([0, max_value]),
-            transform=source_rasters.geospatial_profile["transform"],
-            compress="LZW",
-            crs=source_rasters.geospatial_profile["crs"],
+        f"{os.path.splitext(destination)[0]}_{rw_window.nr:05}.tif",
+        "w",
+        driver="GTiff",
+        width=rw_window.rio_window.width,
+        height=rw_window.rio_window.height,
+        count=1,
+        dtype=rio.dtypes.get_minimum_dtype([0, max_value]),
+        transform=rw_window.transform,
+        compress="LZW",
+        crs=source_rasters.geospatial_profile["crs"],
     ) as dest:
         dest.update_tags(
             creation_date=datetime.datetime.now().strftime("%d-%b-%Y_%H:%M:%S"),
@@ -73,6 +72,7 @@ def write_target_raster_chunk(
             indexes=1,
         )
 
+    logger.info(f"Writing chunk {rw_window.nr} out of {rw_window.total} to file.")
 
 
 @task
diff --git a/src/windows.py b/src/windows.py
new file mode 100644
index 0000000..2764858
--- /dev/null
+++ b/src/windows.py
@@ -0,0 +1,100 @@
+import random
+import prefect
+import affine
+import numpy as np
+import rasterio as rio
+from prefect import task
+from rasterio.windows import Window
+
+try:
+    from source_rasters import SourceRasters
+except ModuleNotFoundError:
+    from src.source_rasters import SourceRasters
+
+
+class CombineWindow:
+    """
+    A single read/write window and its associated unique combinations
+    """
+
+    def __init__(
+        self,
+        row_start: int,
+        row_stop: int,
+        column_start: int,
+        column_stop: int,
+        nr: int,
+        totals: int,
+        top_left_x: int,
+        top_left_y: int,
+        resolution: int,
+    ):
+        self.rio_window = Window.from_slices(
+            (row_start, row_stop), (column_start, column_stop)
+        )
+        self.unique_combinations = None
+        self.nr = nr
+        self.total = totals
+
+        self.transform = affine.Affine(
+            a=resolution, b=0, c=top_left_x, d=0, e=resolution * -1, f=top_left_y
+        )
+
+    def set_unique_combinations(self, uc: set):
+        self.unique_combinations = uc
+
+    def get_unique_combinations(self):
+        return self.unique_combinations
+
+
+@task
+def get_rw_windows(
+    source_rasters: SourceRasters,
+    window_height: int = 2000,
+    window_width: int = 2000,
+    sample: bool = False,
+) -> list:
+    """ """
+
+    logger = prefect.context.get("logger")
+
+    row_starts = range(
+        0, (source_rasters.geospatial_profile["height"] - window_height), window_height
+    )
+    column_starts = range(
+        0, (source_rasters.geospatial_profile["width"] - window_width), window_width
+    )
+    windows = []
+    n = 0
+    total_windows = np.multiply(len(row_starts), len(column_starts))
+    for row_start in row_starts:
+        for column_start in column_starts:
+            windows.append(
+                CombineWindow(
+                    row_start=row_start,
+                    row_stop=row_start + window_height,
+                    column_start=column_start,
+                    column_stop=column_start + window_width,
+                    nr=n,
+                    totals=total_windows,
+                    top_left_x=(
+                        getattr(rio.open(source_rasters.source_list[0]), "transform")
+                        * (column_start, row_start)
+                    )[0],
+                    top_left_y=(
+                        getattr(rio.open(source_rasters.source_list[0]), "transform")
+                        * (column_start, row_start)
+                    )[1],
+                    resolution=getattr(
+                        getattr(rio.open(source_rasters.source_list[0]), "transform"),
+                        "a",
+                    ),
+                )
+            )
+            n += 1
+    logger.info(f"Created {n} windows of size {window_height}X{window_width}")
+
+    if sample:
+        return random.sample(windows, 20)
+    else:
+        return windows
diff --git a/windows.py b/windows.py
deleted file mode 100644
index 973c26f..0000000
--- a/windows.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import random
-import prefect
-import affine
-import rasterio as rio
-from prefect import task
-from rasterio.windows import Window
-
-try:
-    from source_rasters import SourceRasters
-except ModuleNotFoundError:
-    from src.source_rasters import SourceRasters
-
-
-class CombineWindow:
-    """
-    A single read/write window and its associated unique combinations
-    """
-
-    def __init__(self, row_start: int, row_stop: int, column_start: int, column_stop: int, nr: int,
-                 top_left_x: int, top_left_y: int, resolution: int):
-        self.rio_window = Window.from_slices(
-            (row_start, row_stop), (column_start, column_stop)
-        )
-        self.unique_combinations = None
-        self.nr = nr
-        self.transform = affine.Affine(a=resolution,
-                                      b=0,
-                                      c=top_left_x,
-                                      d=0,
-                                      e=resolution*-1,
-                                      f=top_left_y)
-
-
-    def set_unique_combinations(self, uc: set):
-        self.unique_combinations = uc
-
-    def get_unique_combinations(self):
-        return self.unique_combinations
-
-
-@task
-def get_rw_windows(
-    source_rasters: SourceRasters,
-    window_rows: int = 2000,
-    window_columns: int = 2000,
-    sample: bool = False,
-) -> list:
-
-    logger = prefect.context.get("logger")
-
-    row_starts = range(0, (source_rasters.geospatial_profile['height'] - window_rows), window_rows)
-    column_starts = range(0, (source_rasters.geospatial_profile['width'] - window_columns), window_columns)
-    windows = []
-    n = 0
-    for row_start in row_starts:
-        for column_start in column_starts:
-            windows.append(
-                CombineWindow(
-                    row_start=row_start,
-                    row_stop=row_start + window_rows,
-                    column_start=column_start,
-                    column_stop=column_start + window_columns,
-                    nr=n,
-                    top_left_x=(getattr(rio.open(source_rasters.src_list[0]), 'transform') * (column_start, row_start))[0],
-                    top_left_y=(getattr(rio.open(source_rasters.src_list[0]), 'transform') * (column_start, row_start))[1],
-                    resolution=getattr(getattr(rio.open(source_rasters.src_list[0]), 'transform'), 'a'),
-                )
-            )
-            n += 1
-    logger.info(
-                f"Created {n} windows of size {window_rows}X{window_columns}"
-            )
-
-    if sample:
-        return random.sample(windows, 20)
-    else:
-        return windows
-- 
GitLab