From 260cbe8cf1795a7ec6f799b766c4cb7304427e7b Mon Sep 17 00:00:00 2001 From: jchemutt Date: Fri, 12 Apr 2024 14:54:14 +0300 Subject: [PATCH 1/4] updated readme --- README.md | 3 +-- src/run_scripts.sh | 17 ----------------- 2 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 src/run_scripts.sh diff --git a/README.md b/README.md index 8e2e72b..1ad4096 100644 --- a/README.md +++ b/README.md @@ -49,5 +49,4 @@ You will need a private_key.json file associated with service_account placed in ``` -There is an sh file to run the scripts run_scripts.sh I recommend setting up a root cron job to run it. -Before you run it with cron you will need to chmod to 755 so it can be executed properly. +There is master_script.py to run all the other scripts. diff --git a/src/run_scripts.sh b/src/run_scripts.sh deleted file mode 100644 index b47aaeb..0000000 --- a/src/run_scripts.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# Activate the Anaconda environment -source /opt/anaconda3/bin/activate /opt/anaconda3/envs/Biomass_Pipeline - -cd /opt/Biomass - -# Run each Python script sequentially -/opt/anaconda3/envs/Biomass_Pipeline/bin/python /opt/Biomass/data_extraction.py -/opt/anaconda3/envs/Biomass_Pipeline/bin/python /opt/Biomass/gwr_model.py -/opt/anaconda3/envs/Biomass_Pipeline/bin/python /opt/Biomass/rasterize.py -/opt/anaconda3/envs/Biomass_Pipeline/bin/python /opt/Biomass/import_biomass.py - - - -# Deactivate the Anaconda environment -conda deactivate From 2032247c019b1beccc384d26e110f0d80e0fbfd8 Mon Sep 17 00:00:00 2001 From: jchemutt Date: Fri, 12 Apr 2024 16:54:44 +0300 Subject: [PATCH 2/4] updated master script --- .../import_biomass.cpython-312.pyc | Bin 0 -> 3022 bytes .../__pycache__/rasterize.cpython-312.pyc | Bin 5481 -> 5480 bytes src/codes/gwr_model.py | 5 -- src/codes/import_biomass.py | 8 +-- src/codes/master_script.py | 2 +- src/codes/mosaic.zip | Bin 0 -> 313205 bytes src/codes/rasterize.py | 6 -- .../test_data_extraction.cpython-312.pyc | Bin 1817 -> 0 bytes .../test_gwr_model.cpython-312.pyc | Bin 3004 -> 0 bytes .../test_import_biomass.cpython-312.pyc | Bin 4054 -> 0 bytes .../test_rasterize.cpython-312.pyc | Bin 3628 -> 3461 bytes src/tests/test_data_extraction.py | 29 ---------- src/tests/test_gwr_model.py | 43 --------------- src/tests/test_import_biomass.py | 52 ------------------ src/tests/test_rasterize.py | 26 ++++----- 15 files changed, 16 insertions(+), 155 deletions(-) create mode 100644 src/codes/__pycache__/import_biomass.cpython-312.pyc create mode 100644 src/codes/mosaic.zip delete mode 100644 src/tests/__pycache__/test_data_extraction.cpython-312.pyc delete mode 100644 src/tests/__pycache__/test_gwr_model.cpython-312.pyc delete mode 100644 src/tests/__pycache__/test_import_biomass.cpython-312.pyc delete mode 100644 src/tests/test_data_extraction.py delete mode 100644 src/tests/test_gwr_model.py delete mode 100644 src/tests/test_import_biomass.py diff --git a/src/codes/__pycache__/import_biomass.cpython-312.pyc b/src/codes/__pycache__/import_biomass.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f334d26eb0ec7dc3c79d744aff42aa30be2c50a3 GIT binary patch literal 3022 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 J9k;RZ{{#46Rki>C literal 0 HcmV?d00001 diff --git a/src/codes/rasterize.py b/src/codes/rasterize.py index 5e7b491..b45c4ed 100644 --- a/src/codes/rasterize.py +++ b/src/codes/rasterize.py @@ -20,12 +20,6 @@ # Constants -filepath = '../data.json' - -with open(filepath) as f: - data = json.load(f) - - outputs_path = '../outputs' data_path='../data' diff --git a/src/tests/__pycache__/test_data_extraction.cpython-312.pyc b/src/tests/__pycache__/test_data_extraction.cpython-312.pyc deleted file mode 100644 index 00daed54f0c4789c30b31f819c437cec63cc770e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1817 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 diff --git a/src/tests/__pycache__/test_rasterize.cpython-312.pyc b/src/tests/__pycache__/test_rasterize.cpython-312.pyc index 902d803bf2dbb30b96e13013b59e3dfde1c9b0a7..ee64284f8342ac1f646692dacbc9fda259a998aa 100644 GIT binary patch delta 1014 zcmZ8gO=uHA6yDj){v_F~+D6SLtx0VnM5VU%r$5*P`iHgPMFlS!*6b!ml5Ch=g+i4c z6j~J8GD3Usq9>&V5ig#47DQ}_rMmQ{HxV>?@*uuR8xwC#+cJ38$Y`(jC+><5{v?nF$Z5wm$9V=)q< zd9iO~F95qA+zj_gOROL2uW19b>U&w)l-sLv`*L|TyV;ehcBS6Q=>{9B%Atp?%U5dJ z(I@(b+)cvtv#9Ym5naG>dRWSZjlc?mgkZP$e}0rVRQg1k^s9fO9{Nk_Kpq;Ck6@3n zOIv)jKVaCGXI94;);7j##CPMGE;snY1&eHA_t0F*8KB z9g}2og`#P@LbhnxrpsHlD-{d2V-yJK05v&C?|Ivf;_WVp+ux8*mPh$FfsKKRfkDgO zc*n#DK)XsqK1coAu`M~WOsVgDBn;8)PW^D?I0;r`;IHUBKE^wU4oYn;2H&i2l)HQq zT7{@jI>0*|?e+Iu;iu6G8xvSlhPeBEn6<)luF(e43&Es724HhVVwS9%CK+S^S9Ir^ zi?3USa`Ot{MkoFZ{v%FYOn}rL1qXwdee>Qq?|Mu8ot)ST?pr#$cy>M7TMHhqbI6;X z9oo}61|`#CN(&dICE*{#=t%0 z8VV9(1bYDu#~zH$uIL@Ejs+oIZ^1%OU6F+|=z9bHiL<3F!6%}@O7A~Y8bO>e*?Z@@;Cqh delta 1203 zcmZuwU1$_X9G}_SkGZ?Oi}^CQ`7nviB|T#g6^aT??3us8-i$*dq|C#^SZ|47X zsco)3{xlYgAXvNWwfu1SPW%?eyV!l4jF{3zbViwwQ_9_!_&&xr*q@<)A|Wv4do9gk z!bf{ed=qnTgfN;wDIrVi;hqwF!Et?=S|#Uui?)EsIhU>T)f6wJ8x+x3=& zSyxln&Y(uySXG%}pOAt2PvHeWnx{@lcWB|eg3YE$b9WH1FXf7kYtasFq7)0RXBH^! z1&;Qy+oZiWL=#*kQ^WNv>Z|Lgo-Y(3as1m|UA)@=kzu(LIQIz~3VRA^oBg7it+0pT zuW?Z8Jsv3Euk}sf`N9Zd!3o*P7TfwEsGQEftsgm>%^XjA z=e?BVx8$g0c$S{0mOHkt&KGQ>NC)AS^;pHS;f?vSbsl`(O%(?dzumI{lA~PM0%mg8 zDNvsbGE$hd(i_HG*nSLf?oJ?l1UjFSZs?3Fbu)F>gsM_es_{yEzVGwJL}rN`4q79d zB0kY|+bCJO?niX?D4O`Dm4BP3mvT7DJCTk6xq$*7%KMY@AqfZ{bC(zNB3czC>CkFi zka|~DQQEtzD$*!kYY0h07-q0v?ZF-FE496^hx;A?;!F0qQhCA`>@pqZylj-qmTmgt zxC4FjyE>2_P~gmz$Cc lP03e?b1O$M64lF-&qCS@v3`2=mlHpoxb)>p2#Ku$;QtH&9EJb@ diff --git a/src/tests/test_data_extraction.py b/src/tests/test_data_extraction.py deleted file mode 100644 index 4003b84..0000000 --- a/src/tests/test_data_extraction.py +++ /dev/null @@ -1,29 +0,0 @@ -import unittest -from unittest.mock import MagicMock, patch -import pandas as pd -import sys,os -sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) -from codes.data_extraction import * - -class TestGetImage(unittest.TestCase): - - @patch('codes.data_extraction.ee.ImageCollection') - def test_getImage(self, mock_ImageCollection): - # Mock the ImageCollection - mock_collection = MagicMock() - mock_ImageCollection.return_value = mock_collection - - # Call the function - result = getImage("MODIS/061/MOD13A2", "2024-01-01", "2024-01-31", "NDVI") - - # Assertions - mock_ImageCollection.assert_called_once_with("MODIS/061/MOD13A2") - mock_collection.filter.assert_called_once_with( - ee.Filter.date("2024-01-01", "2024-01-31")) - mock_collection.select.assert_called_once_with("NDVI") - self.assertEqual(result, mock_collection) - - # Add more tests for other functions... - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/src/tests/test_gwr_model.py b/src/tests/test_gwr_model.py deleted file mode 100644 index 17b9930..0000000 --- a/src/tests/test_gwr_model.py +++ /dev/null @@ -1,43 +0,0 @@ -import unittest -import pandas as pd -import numpy as np -from geopandas import GeoDataFrame -from mgwr.gwr import GWR -import sys,os -sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) -from codes.gwr_model import * - -class TestGwrModel(unittest.TestCase): - def setUp(self): - # Create a temporary CSV file with test data - self.test_data = pd.DataFrame({'lon': [1, 2, 3], 'lat': [4, 5, 6], 'ndvi': [0.1, 0.2, 0.3], - 'sm': [0.4, 0.5, 0.6], 'preci': [0.7, 0.8, 0.9]}) - self.test_data.to_csv('test_data.csv', index=False) - - def tearDown(self): - # Clean up temporary files after each test - os.remove('test_data.csv') - - def test_process_data(self): - # Test loading and processing data from a CSV file - processed_data = process_data('test_data.csv') - self.assertIsInstance(processed_data, GeoDataFrame) - self.assertEqual(len(processed_data), 3) # Assuming 3 rows of test data - - def test_run_gwr_model(self): - # Test running GWR model and generating predictions - processed_data = process_data('test_data.csv') - results = run_gwr_model(processed_data) - self.assertIsInstance(results, GWR) - self.assertEqual(len(results.predictions), 3) # Assuming 3 rows of test data - - def test_output_results(self): - # Test writing results to a CSV file - output_path = 'test_results.csv' - processed_data = process_data('test_data.csv') - results = run_gwr_model(processed_data) - output_path = output_results(results, output_path) - self.assertTrue(os.path.isfile(output_path)) - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/src/tests/test_import_biomass.py b/src/tests/test_import_biomass.py deleted file mode 100644 index ccc9eda..0000000 --- a/src/tests/test_import_biomass.py +++ /dev/null @@ -1,52 +0,0 @@ -import unittest -from unittest.mock import MagicMock -import sys,os -sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) -from codes.tools import GeoserverClient - - -class TestImportBiomass(unittest.TestCase): - - def setUp(self): - # Set up test data and parameters - self.geo_url = 'test_geoserver_url' - self.geo_user = 'test_geoserver_user' - self.geo_pwd = 'test_geoserver_pwd' - self.workspace_name = 'test_workspace' - self.forecast_type = 'test_forecast' - self.folder_data = 'test_data_folder' - self.outputs_path = 'test_outputs_path' - self.folder_layers = os.path.join(self.folder_data, "layers") - self.folder_properties = os.path.join(self.folder_layers, self.forecast_type+"_properties") - self.folder_tmp = os.path.join(self.folder_data, "tmp") - self.fname = os.path.join(self.outputs_path, "new_data_list_FINAL.txt") - - with open(self.fname, 'w') as f: - f.write("biomass_20240101.tif\n") - - def test_geoserver_interaction(self): - # Mock GeoserverClient - geoclient = GeoserverClient(self.geo_url, self.geo_user, self.geo_pwd) - geoclient.connect = MagicMock() - geoclient.get_workspace = MagicMock(return_value=self.workspace_name) - geoclient.get_store = MagicMock(return_value=None) - geoclient.create_mosaic = MagicMock() - geoclient.update_mosaic = MagicMock() - - # Call the script function - import_script_function(self.geo_url, self.geo_user, self.geo_pwd, self.workspace_name, self.forecast_type, self.folder_data, self.outputs_path) - - # Assertions - geoclient.connect.assert_called_once() - geoclient.get_workspace.assert_called_once_with(self.workspace_name) - geoclient.get_store.assert_called_once_with(self.forecast_type) - geoclient.create_mosaic.assert_called_once() - geoclient.update_mosaic.assert_not_called() # Assuming the store is not found, so only create_mosaic should be called - - def tearDown(self): - # Clean up temporary files or resources if any - if os.path.exists(self.fname): - os.remove(self.fname) - -if __name__ == '__main__': - unittest.main() diff --git a/src/tests/test_rasterize.py b/src/tests/test_rasterize.py index b554e91..a531540 100644 --- a/src/tests/test_rasterize.py +++ b/src/tests/test_rasterize.py @@ -16,31 +16,29 @@ def setUp(self): 'biom': [1.79040380360565, 1.78896823494216, 1.79198639098456]}) self.test_data.to_csv('test_results.csv', index=False) - def tearDown(self): - # Clean up temporary files after each test - os.remove('test_results.csv') - #for file in os.listdir('temp_raster_files'): - #os.remove(os.path.join('temp_raster_files', file)) + def test_process_data(self): # Test if process_data function correctly converts CSV to GeoDataFrame - self.test_data = process_data('test_results.csv') - self.assertIsInstance(self.test_data, gpd.GeoDataFrame) - self.assertEqual(len(self.test_data), 3) # Assuming 3 rows of test data + processed_data = process_data('test_results.csv') + self.assertIsInstance(processed_data, gpd.GeoDataFrame) + self.assertEqual(len(processed_data), 3) # Assuming 3 rows of test data def test_create_raster_files(self): # Test if create_raster_files function correctly generates raster files raster = rasterio.open('test_raster.tif', 'w', driver='GTiff', height=300, width=260, count=1,dtype='float32', crs='EPSG:4326', transform=rasterio.transform.from_origin(36, 15, 0.05, 0.05)) - create_raster_files(self.test_data, 'temp_raster_files', raster) + processed_data = process_data('test_results.csv') + create_raster_files(processed_data, 'temp_raster_files', raster) raster.close() raster_files = os.listdir('temp_raster_files') self.assertEqual(len(raster_files), 1) # Assuming only one raster file is created self.assertTrue(raster_files[0].startswith('biomass_20240101')) # Assuming the file name follows a certain pattern - - def test_create_fresh_list_final(self): - # Test if create_fresh_list_final function correctly creates or updates the output file - create_fresh_list_final() - self.assertTrue(os.path.exists('new_data_list_FINAL.txt')) # Assuming the output file is created or updated + + def tearDown(self): + # Clean up temporary files after each test + os.remove('test_results.csv') + for file in os.listdir('temp_raster_files'): + os.remove(os.path.join('temp_raster_files', file)) if __name__ == '__main__': unittest.main() From e23a56deb17bce157d9c74c50361758793c693ca Mon Sep 17 00:00:00 2001 From: jchemutt Date: Fri, 12 Apr 2024 16:55:39 +0300 Subject: [PATCH 3/4] updated master script --- src/codes/mosaic.zip | Bin 313205 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/codes/mosaic.zip diff --git a/src/codes/mosaic.zip b/src/codes/mosaic.zip deleted file mode 100644 index 1a64d6d8d2d51590a3397a6e2a9d5320c832d814..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 313205 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 J9k;RZ{{#46Rki>C From 5755d68c13c48af526e292c39b48f10a8ffa8fe3 Mon Sep 17 00:00:00 2001 From: jchemutt Date: Wed, 17 Apr 2024 17:21:12 +0300 Subject: [PATCH 4/4] added github workflows --- .github/workflows/pipeline.yml | 116 +++++++++++++++++++++++++++++++++ src/codes/data_extraction.py | 12 ++-- src/codes/gwr_model.py | 3 +- src/codes/import_biomass.py | 7 +- src/codes/rasterize.py | 5 +- src/tests/test_raster.tif | Bin 313664 -> 0 bytes src/tests/test_rasterize.py | 24 ++++--- 7 files changed, 147 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/pipeline.yml delete mode 100644 src/tests/test_raster.tif diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml new file mode 100644 index 0000000..a5adc3f --- /dev/null +++ b/.github/workflows/pipeline.yml @@ -0,0 +1,116 @@ +# This workflow will install Python dependencies, run tests and lint with a single version of Python +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: Devops FORAGE_ETL + +on: + push: + branches: ["stage"] + tags: + - "v*" + +permissions: + contents: read + +jobs: + # ------- START ORM PROCCESS -------- # + + TestETL: + runs-on: ubuntu-latest + defaults: + run: + shell: bash -el {0} + + steps: + - uses: actions/checkout@v4 + - name: Set up Conda + uses: conda-incubator/setup-miniconda@v3 + with: + activate-environment: Biomass_Pipeline + environment-file: ./src/environment.yml + python-version: 3.12 + auto-activate-base: false + + - name: Run Tests + run: | + python -m unittest discover -s ./src/tests/ -p 'test_*.py' + # ------- END ORM PROCCESS -------- # + # ------- START MERGE PROCCESS -------- # + + MergeMainETL: + needs: TestETL + name: Merge Stage with Main + permissions: write-all + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + + - name: Merge stage -> main + uses: devmasx/merge-branch@master + with: + type: now + head_to_merge: ${{ github.ref }} + target_branch: main + github_token: ${{ github.token }} + + # ------- END MERGE PROCCESS -------- # + + # ------- START RELEASE PROCCESS -------- # + + PostRelease: + needs: MergeMainETL + name: Create Release + runs-on: ubuntu-latest + permissions: write-all + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: "0" + - uses: actions/setup-node@v3 + with: + node-version: 18 + # API Zip + - name: Zip artifact for deployment + run: zip releaseForageEtl.zip ./src/* -r + # Upload Artifacts + - name: Upload Api artifact for deployment job + uses: actions/upload-artifact@v3 + with: + name: ForageEtl + path: releaseForageEtl.zip + # Generate Tagname + - name: Generate Tagname for release + id: taggerDryRun + uses: anothrNick/github-tag-action@1.61.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + WITH_V: true + DRY_RUN: true + DEFAULT_BUMP: patch + RELEASE_BRANCHES: stage,main + BRANCH_HISTORY: last + # Create release + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + tag_name: ${{ steps.taggerDryRun.outputs.new_tag }} + release_name: Release ${{ steps.taggerDryRun.outputs.new_tag }} + #body_path: ./body.md + body: ${{ github.event.head_commit.message }} + draft: false + prerelease: false + # Upload Assets to release + - name: Upload Release Asset API + id: upload-api-release-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps + asset_path: ./releaseForageEtl.zip + asset_name: releaseForageEtl.zip + asset_content_type: application/zip +# ------- END RELEASE PROCCESS -------- # diff --git a/src/codes/data_extraction.py b/src/codes/data_extraction.py index b6be87b..d352c0e 100644 --- a/src/codes/data_extraction.py +++ b/src/codes/data_extraction.py @@ -20,16 +20,18 @@ # Constants -filepath = '../data.json' +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +filepath = os.path.join(project_root, 'data.json') + with open(filepath) as f: data = json.load(f) -private_key = '../private_key.json' -outputs_path = '../outputs' -inputs_path = '../inputs' -data_path='../data' +private_key = os.path.join(project_root, 'private_key.json') +outputs_path = os.path.join(project_root, 'outputs') +inputs_path = os.path.join(project_root, 'inputs') +data_path = os.path.join(project_root, 'data') layers_path = os.path.join(data_path, "layers") biomass_path = os.path.join(layers_path, "biomass_et") grid_points=os.path.join(inputs_path, "grid_points.xlsx") diff --git a/src/codes/gwr_model.py b/src/codes/gwr_model.py index 7133196..bdbd790 100644 --- a/src/codes/gwr_model.py +++ b/src/codes/gwr_model.py @@ -12,8 +12,9 @@ from codes.funcs import * # Constants +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -outputs_path = '../outputs' +outputs_path = os.path.join(project_root, 'outputs') combined_output=os.path.join(outputs_path, "combined.csv") diff --git a/src/codes/import_biomass.py b/src/codes/import_biomass.py index 188a491..b90017c 100644 --- a/src/codes/import_biomass.py +++ b/src/codes/import_biomass.py @@ -14,7 +14,8 @@ # Constants -filepath = '../data.json' +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +filepath = os.path.join(project_root, 'data.json') with open(filepath) as f: data = json.load(f) @@ -27,8 +28,8 @@ workspace_name = "waterpoints_et" forecast_type = "biomass" country_iso = workspace_name.split("_")[1] -folder_data = '../data' -outputs_path = '../outputs' +folder_data = os.path.join(project_root, 'data') +outputs_path = os.path.join(project_root, 'outputs') folder_layers = os.path.join(folder_data, "layers") folder_properties = os.path.join(folder_layers, forecast_type+"_properties") folder_tmp = os.path.join(folder_data, "tmp") diff --git a/src/codes/rasterize.py b/src/codes/rasterize.py index b45c4ed..65be87c 100644 --- a/src/codes/rasterize.py +++ b/src/codes/rasterize.py @@ -20,8 +20,9 @@ # Constants -outputs_path = '../outputs' -data_path='../data' +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +outputs_path = os.path.join(project_root, 'outputs') +data_path = os.path.join(project_root, 'data') layers_path = os.path.join(data_path, "layers") diff --git a/src/tests/test_raster.tif b/src/tests/test_raster.tif deleted file mode 100644 index f2000abb7dddd991fa3abbf1f16f91c2c973eece..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 313664 zcmeIwKWh|090uTbXO|c;NG$wQ=n>FLMN(J@R~T)?E}(FhDQ$$HS6T!W&PuKlv`Qg@ zkYM}Rda^{kpkR`9jm>R;}Hr6Bkd_FU|6qI(NC|e$CJNy?ScRlUZ(S{rua7^y7Zr=gqr? z%+>t6=I@g>OEq69$9oH3c9ZqJCI^R2R!hn5pk#SivNZ03JV`cs`de*SR% z?EKE8|INAMF?s)D{PEhCm;HV#U!OjEFnaW4>E7Mf^-&{0fB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+0D=D@@CWJk BVd?+? diff --git a/src/tests/test_rasterize.py b/src/tests/test_rasterize.py index a531540..8a6a0fc 100644 --- a/src/tests/test_rasterize.py +++ b/src/tests/test_rasterize.py @@ -10,35 +10,41 @@ class TestRasterize(unittest.TestCase): def setUp(self): + self.project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) + self.outputs_path = os.path.join(self.project_root, 'outputs') + self.temp_raster_files=os.path.join(self.outputs_path, 'temp_raster_files') + self.test_results= os.path.join(self.outputs_path, "test_results.csv") + os.makedirs(self.temp_raster_files, exist_ok=True) + self.test_raster= os.path.join(self.outputs_path, "test_raster.tif") # Create a temporary results CSV file with test data self.test_data = pd.DataFrame({'lon': [39.41, 39.445, 39.492], 'lat': [3.271, 3.261, 3.254], 'date': [20240101,20240101,20240101],'year': [2024, 2024, 2024], 'month': [1, 1, 1], 'day': [1, 1, 1], 'biom': [1.79040380360565, 1.78896823494216, 1.79198639098456]}) - self.test_data.to_csv('test_results.csv', index=False) + self.test_data.to_csv(self.test_results, index=False) def test_process_data(self): # Test if process_data function correctly converts CSV to GeoDataFrame - processed_data = process_data('test_results.csv') + processed_data = process_data(self.test_results) self.assertIsInstance(processed_data, gpd.GeoDataFrame) self.assertEqual(len(processed_data), 3) # Assuming 3 rows of test data def test_create_raster_files(self): # Test if create_raster_files function correctly generates raster files - raster = rasterio.open('test_raster.tif', 'w', driver='GTiff', height=300, width=260, count=1,dtype='float32', crs='EPSG:4326', transform=rasterio.transform.from_origin(36, 15, 0.05, 0.05)) - processed_data = process_data('test_results.csv') - create_raster_files(processed_data, 'temp_raster_files', raster) + raster = rasterio.open(self.test_raster, 'w', driver='GTiff', height=300, width=260, count=1,dtype='float32', crs='EPSG:4326', transform=rasterio.transform.from_origin(36, 15, 0.05, 0.05)) + processed_data = process_data(self.test_results) + create_raster_files(processed_data, self.temp_raster_files, raster) raster.close() - raster_files = os.listdir('temp_raster_files') + raster_files = os.listdir(self.temp_raster_files) self.assertEqual(len(raster_files), 1) # Assuming only one raster file is created self.assertTrue(raster_files[0].startswith('biomass_20240101')) # Assuming the file name follows a certain pattern def tearDown(self): # Clean up temporary files after each test - os.remove('test_results.csv') - for file in os.listdir('temp_raster_files'): - os.remove(os.path.join('temp_raster_files', file)) + os.remove(self.test_results) + for file in os.listdir(self.temp_raster_files): + os.remove(os.path.join(self.temp_raster_files, file)) if __name__ == '__main__': unittest.main()