openforis-whisp 3.0.0a7__py3-none-any.whl → 3.0.0a9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -373,15 +373,25 @@ def g_esri_2020_2023_crop_prep():
373
373
  #### disturbances by year
374
374
 
375
375
  # RADD_year_2019 to RADD_year_< current year >
376
+ # Coverage: Primary humid tropical forest areas of South America, sub-Saharan Africa,
377
+ # and insular Southeast Asia at 10m spatial resolution.
378
+ # Available from January 2019 to present for Africa,
379
+ # and from January 2020 to present for South America and Southeast Asia.
376
380
  def g_radd_year_prep():
377
- from datetime import datetime
378
-
381
+ """
382
+ RADD alerts per year as multiband image.
383
+ Each band is binary (1 = alert detected).
384
+ Coverage: Primary humid tropical forest areas of South America, sub-Saharan Africa,
385
+ and insular Southeast Asia at 10m spatial resolution.
386
+ Available from January 2019 to present for Africa,
387
+ and from January 2020 to present for South America and Southeast Asia.
388
+ """
379
389
  radd = ee.ImageCollection("projects/radar-wur/raddalert/v1")
380
390
  radd_date = (
381
391
  radd.filterMetadata("layer", "contains", "alert").select("Date").mosaic()
382
392
  )
383
393
  start_year = 19
384
- current_year = datetime.now().year % 100
394
+ current_year = CURRENT_YEAR_2DIGIT
385
395
 
386
396
  def make_band(year, img_stack):
387
397
  start = year * 1000
@@ -584,27 +594,412 @@ def g_radd_before_2020_prep():
584
594
  ).selfMask()
585
595
 
586
596
 
587
- # # DIST_after_2020
588
- # # alerts only for after 2020 currently so need to use date
589
- # def glad_dist_after_2020_prep():
597
+ # DIST_after_2020
598
+
599
+ # DIST alerts are for all veg types so masked by EUFO forest 2020
600
+ # NB alerts only for 2024 onwards (in GEE at least, available for 2023 ofrom the GLAD site)
601
+ # for conistency using "...after_2020..." terminology.
602
+ def g_glad_dist_after_2020_prep():
603
+
604
+ # no need to filter by date as all dates are later than 2023
605
+
606
+ # Load the vegetation disturbance collections
607
+ VEGDISTSTATUS = ee.ImageCollection(
608
+ "projects/glad/HLSDIST/current/VEG-DIST-STATUS"
609
+ ).mosaic()
610
+
611
+ # Key for high-confidence alerts (values 3, 6, 7, 8)
612
+ high_conf_values = [3, 6, 7, 8]
613
+
614
+ # Create high-confidence mask
615
+ dist_high_conf = VEGDISTSTATUS.remap(
616
+ high_conf_values, [1] * len(high_conf_values), 0
617
+ )
618
+
619
+ return dist_high_conf.updateMask(g_jrc_gfc_2020_prep()).rename(
620
+ "DIST_after_2020"
621
+ ) # Mask alerts to forest and rename band
622
+
623
+
624
+ # # DIST_alert_2024 to DIST_alert_< current year >
625
+ # # Notes:
626
+ # # 1) so far only available for 2024 onwards in GEE
627
+ # # 2) masked alerts (as dist alerts are for all vegetation) to JRC EUFO 2020 layer, as close to EUDR definition
628
+
629
+
630
+ def g_glad_dist_year_prep():
631
+ """
632
+ GLAD DIST alerts per year as multiband image.
633
+ Each band is binary (1 = high-confidence disturbance alert).
634
+ Uses VEG-DIST-DATE to filter by year, VEG-DIST-STATUS for confidence.
635
+ Masked to EUFO 2020 forest.
636
+ Note: Only available from 2024 onwards.
637
+ Fully server-side using ee.List.iterate (no Python for loop).
638
+ """
639
+ # Load the vegetation disturbance collections
640
+ # Vegetation disturbance status (0-8, class flag, 8-bit)
641
+ VEGDISTSTATUS = ee.ImageCollection(
642
+ "projects/glad/HLSDIST/current/VEG-DIST-STATUS"
643
+ ).mosaic()
644
+ # Initial vegetation disturbance date (>0: days since 2020-12-31, 16-bit)
645
+ VEGDISTDATE = ee.ImageCollection(
646
+ "projects/glad/HLSDIST/current/VEG-DIST-DATE"
647
+ ).mosaic()
648
+
649
+ # Key for high-confidence alerts (values 3, 6, 7, 8)
650
+ # 3 = <50% loss, high confidence, ongoing
651
+ # 6 = ≥50% loss, high confidence, ongoing
652
+ # 7 = <50% loss, high confidence, finished
653
+ # 8 = ≥50% loss, high confidence, finished
654
+ high_conf_values = [3, 6, 7, 8]
655
+ dist_high_conf = VEGDISTSTATUS.remap(
656
+ high_conf_values, [1] * len(high_conf_values), 0
657
+ )
658
+
659
+ # Year range: 2024 to current year
660
+ start_year = 2024
661
+ end_year = CURRENT_YEAR
662
+
663
+ # Reference date for day offset calculation (2020-12-31)
664
+ ref_date = ee.Date("2020-12-31")
665
+
666
+ # Create first band (2024)
667
+ first_year = ee.Number(start_year)
668
+ first_start_days = ee.Date.fromYMD(first_year, 1, 1).difference(ref_date, "day")
669
+ first_end_days = ee.Date.fromYMD(first_year.add(1), 1, 1).difference(
670
+ ref_date, "day"
671
+ )
672
+ first_year_mask = VEGDISTDATE.gte(first_start_days).And(
673
+ VEGDISTDATE.lt(first_end_days)
674
+ )
675
+ first_band_name = ee.String("DIST_year_").cat(first_year.format("%d"))
676
+ first_band = (
677
+ first_year_mask.updateMask(dist_high_conf).rename(first_band_name).selfMask()
678
+ )
679
+
680
+ # Server-side iteration to add remaining years
681
+ years = ee.List.sequence(start_year + 1, end_year)
682
+
683
+ def add_year_band(year, img_stack):
684
+ year_num = ee.Number(year)
685
+ start_days = ee.Date.fromYMD(year_num, 1, 1).difference(ref_date, "day")
686
+ end_days = ee.Date.fromYMD(year_num.add(1), 1, 1).difference(ref_date, "day")
687
+ year_mask = VEGDISTDATE.gte(start_days).And(VEGDISTDATE.lt(end_days))
688
+ band_name = ee.String("DIST_year_").cat(year_num.format("%d"))
689
+ year_band = year_mask.updateMask(dist_high_conf).rename(band_name).selfMask()
690
+ return ee.Image(img_stack).addBands(year_band)
691
+
692
+ img_stack = ee.Image(years.iterate(add_year_band, first_band))
693
+
694
+ # Mask to EUFO 2020 forest
695
+ return img_stack.updateMask(g_jrc_gfc_2020_prep())
696
+
697
+
698
+ # GLAD-L (GLAD Landsat) Alerts
699
+ # Coverage: Entire tropics (30°N to 30°S) from January 1, 2018 to present,
700
+ # and from 2015 to present for select countries in the Amazon, Congo Basin,
701
+ # and insular Southeast Asia.
702
+ # Uses confidence bands per year where values >= 2 are confirmed alerts
703
+ # Asset paths per year:
704
+ # 2021: projects/glad/alert/2021final (conf21)
705
+ # 2022: projects/glad/alert/2022final (conf22)
706
+ # 2023: projects/glad/alert/2023final (conf23)
707
+ # 2024: NOT AVAILABLE
708
+ # 2025+: projects/glad/alert/UpdResult (conf25, conf26, etc.)
709
+ # More info: https://glad.umd.edu/dataset/glad-forest-alerts
710
+
711
+
712
+ # GLAD-L_after_2020 (combined alerts from 2021 to current year, excluding 2024)
713
+ def g_glad_l_after_2020_prep():
714
+ """
715
+ GLAD Landsat alerts after 2020 (combined from 2021 onwards).
716
+ Uses confidence bands with threshold >= 2 for confirmed alerts.
717
+ Note: 2024 data is not available.
718
+ """
719
+ # Load yearly assets and combine into single multiband image
720
+ glad_combined = (
721
+ ee.ImageCollection("projects/glad/alert/2021final")
722
+ .mosaic()
723
+ .select("conf21")
724
+ .addBands(
725
+ ee.ImageCollection("projects/glad/alert/2022final")
726
+ .mosaic()
727
+ .select("conf22")
728
+ )
729
+ .addBands(
730
+ ee.ImageCollection("projects/glad/alert/2023final")
731
+ .mosaic()
732
+ .select("conf23")
733
+ )
734
+ .addBands(
735
+ ee.ImageCollection("projects/glad/alert/UpdResult")
736
+ .mosaic()
737
+ .select(["conf25", "conf26"])
738
+ )
739
+ )
740
+
741
+ # Combine alerts from all available years (confidence >= 2)
742
+ # 2024 not available
743
+ combined_alerts = (
744
+ glad_combined.select("conf21")
745
+ .gte(2)
746
+ .Or(glad_combined.select("conf22").gte(2))
747
+ .Or(glad_combined.select("conf23").gte(2))
748
+ .Or(glad_combined.select("conf25").gte(2))
749
+ .Or(glad_combined.select("conf26").gte(2))
750
+ )
751
+
752
+ return combined_alerts.rename("GLAD-L_after_2020").selfMask()
753
+
590
754
 
591
- # # Load the vegetation disturbance collections
592
- # VEGDISTSTATUS = ee.ImageCollection(
593
- # "projects/glad/HLSDIST/current/VEG-DIST-STATUS"
594
- # ).mosaic()
755
+ # GLAD-L_before_2020 (combined alerts from 2017 to 2020)
756
+ def g_glad_l_before_2020_prep():
757
+ """
758
+ GLAD Landsat alerts before 2020 (combined from 2017-2020 inclusive).
759
+ Uses confidence bands with threshold >= 2 for confirmed alerts.
760
+ Note: 2015 and 2016 assets are not available in GEE.
761
+ Coverage: Tropics (30°N to 30°S).
762
+ """
763
+ # Load yearly assets and combine
764
+ glad_combined = (
765
+ ee.ImageCollection("projects/glad/alert/2017final")
766
+ .mosaic()
767
+ .select("conf17")
768
+ .addBands(
769
+ ee.ImageCollection("projects/glad/alert/2018final")
770
+ .mosaic()
771
+ .select("conf18")
772
+ )
773
+ .addBands(
774
+ ee.ImageCollection("projects/glad/alert/2019final")
775
+ .mosaic()
776
+ .select("conf19")
777
+ )
778
+ .addBands(
779
+ ee.ImageCollection("projects/glad/alert/2020final")
780
+ .mosaic()
781
+ .select("conf20")
782
+ )
783
+ )
595
784
 
596
- # # Key for high-confidence alerts (values 3, 6, 7, 8)
597
- # high_conf_values = [3, 6, 7, 8]
785
+ # Combine alerts from all available years (confidence >= 2)
786
+ combined_alerts = (
787
+ glad_combined.select("conf17")
788
+ .gte(2)
789
+ .Or(glad_combined.select("conf18").gte(2))
790
+ .Or(glad_combined.select("conf19").gte(2))
791
+ .Or(glad_combined.select("conf20").gte(2))
792
+ )
598
793
 
599
- # # Create high-confidence mask
600
- # dist_high_conf = VEGDISTSTATUS.remap(
601
- # high_conf_values, [1] * len(high_conf_values), 0
602
- # )
794
+ return combined_alerts.rename("GLAD-L_before_2020").selfMask()
603
795
 
604
- # return dist_high_conf.updateMask(jrc_gfc_2020_prep()).rename(
605
- # "DIST_after_2020"
606
- # ) # Mask alerts to forest and rename band
607
796
 
797
+ # GLAD-L timeseries - multiband image with one band per year
798
+ def g_glad_l_year_prep():
799
+ """
800
+ GLAD Landsat alerts per year as multiband image.
801
+ Each band is binary (1 = alert with confidence >= 2).
802
+ Coverage: Entire tropics (30°N to 30°S) from January 1, 2018 to present,
803
+ and from 2017 to present for select countries in the Amazon,
804
+ Congo Basin, and insular Southeast Asia.
805
+ Note: 2015 and 2016 assets are not available in GEE.
806
+ Note: 2024 data is not available.
807
+ Includes years from 2017 onwards.
808
+ """
809
+ # Build multiband image with all available years
810
+ # Years 2017-2023 use YYYYfinal assets, 2025+ use UpdResult
811
+ # Note: 2015final and 2016final assets do not exist in GEE
812
+ img_stack = (
813
+ # 2017
814
+ ee.ImageCollection("projects/glad/alert/2017final")
815
+ .mosaic()
816
+ .select("conf17")
817
+ .gte(2)
818
+ .rename("GLAD-L_year_2017")
819
+ .selfMask()
820
+ # 2018
821
+ .addBands(
822
+ ee.ImageCollection("projects/glad/alert/2018final")
823
+ .mosaic()
824
+ .select("conf18")
825
+ .gte(2)
826
+ .rename("GLAD-L_year_2018")
827
+ .selfMask()
828
+ )
829
+ # 2019
830
+ .addBands(
831
+ ee.ImageCollection("projects/glad/alert/2019final")
832
+ .mosaic()
833
+ .select("conf19")
834
+ .gte(2)
835
+ .rename("GLAD-L_year_2019")
836
+ .selfMask()
837
+ )
838
+ # 2020
839
+ .addBands(
840
+ ee.ImageCollection("projects/glad/alert/2020final")
841
+ .mosaic()
842
+ .select("conf20")
843
+ .gte(2)
844
+ .rename("GLAD-L_year_2020")
845
+ .selfMask()
846
+ )
847
+ # 2021
848
+ .addBands(
849
+ ee.ImageCollection("projects/glad/alert/2021final")
850
+ .mosaic()
851
+ .select("conf21")
852
+ .gte(2)
853
+ .rename("GLAD-L_year_2021")
854
+ .selfMask()
855
+ )
856
+ # 2022
857
+ .addBands(
858
+ ee.ImageCollection("projects/glad/alert/2022final")
859
+ .mosaic()
860
+ .select("conf22")
861
+ .gte(2)
862
+ .rename("GLAD-L_year_2022")
863
+ .selfMask()
864
+ )
865
+ # 2023
866
+ .addBands(
867
+ ee.ImageCollection("projects/glad/alert/2023final")
868
+ .mosaic()
869
+ .select("conf23")
870
+ .gte(2)
871
+ .rename("GLAD-L_year_2023")
872
+ .selfMask()
873
+ )
874
+ # 2024 NOT AVAILABLE
875
+ # 2025
876
+ .addBands(
877
+ ee.ImageCollection("projects/glad/alert/UpdResult")
878
+ .mosaic()
879
+ .select("conf25")
880
+ .gte(2)
881
+ .rename("GLAD-L_year_2025")
882
+ .selfMask()
883
+ )
884
+ # 2026
885
+ .addBands(
886
+ ee.ImageCollection("projects/glad/alert/UpdResult")
887
+ .mosaic()
888
+ .select("conf26")
889
+ .gte(2)
890
+ .rename("GLAD-L_year_2026")
891
+ .selfMask()
892
+ )
893
+ )
894
+
895
+ return img_stack
896
+
897
+
898
+ # GLAD-S2 (GLAD Sentinel-2) Alerts
899
+ # GLAD-S2_after_2020 (combined alerts from 2021 to current year)
900
+ def g_glad_s2_after_2020_prep():
901
+ """
902
+ GLAD Sentinel-2 alerts after 2020 (filtered and combined from 2021 onwards - original data starts 2019).
903
+ Uses alert band with threshold >= 2 for confirmed alerts.
904
+ Coverage: Primary humid tropical forest within Amazon basin region.
905
+ https://glad.umd.edu/dataset/glad-forest-alerts
906
+ """
907
+ col = "projects/glad/S2alert"
908
+ s2alert = ee.Image(col + "/alert")
909
+ alert_date = ee.Image(col + "/alertDate")
910
+
911
+ # Date encoding: days since 2019-01-01
912
+ # 2020-12-31 = 730 days (end of 2020)
913
+ days_end_2020 = 730
914
+
915
+ # Filter alerts after 2020 with confidence >= 2
916
+ # - alert: confidence band (0-4, where 4 is highest confidence)
917
+ alerts_after_2020 = s2alert.gte(2).And(alert_date.gt(days_end_2020))
918
+
919
+ return alerts_after_2020.rename("GLAD-S2_after_2020").selfMask()
920
+
921
+
922
+ # GLAD-S2_before_2020 (combined alerts from 2019 to 2020)
923
+ def g_glad_s2_before_2020_prep():
924
+ """
925
+ GLAD Sentinel-2 alerts before 2020 (from 2019-01-01 to 2020-12-31 inclusive).
926
+ Uses alert band with threshold >= 2 for confirmed alerts.
927
+ Coverage: Primary humid tropical forest within Amazon basin region.
928
+ Note: Data starts from 2019.
929
+ """
930
+ col = "projects/glad/S2alert"
931
+ s2alert = ee.Image(col + "/alert")
932
+ alert_date = ee.Image(col + "/alertDate")
933
+
934
+ # Date encoding: days since 2019-01-01
935
+ # 2019-01-01 = 0, 2020-12-31 = 730 days
936
+ days_end_2020 = 730
937
+
938
+ # Filter alerts up to end of 2020 with confidence >= 2
939
+ alerts_before_2020 = s2alert.gte(2).And(alert_date.lte(days_end_2020))
940
+
941
+ return alerts_before_2020.rename("GLAD-S2_before_2020").selfMask()
942
+
943
+
944
+ # GLAD-S2 timeseries - multiband image with one band per year
945
+ def g_glad_s2_year_prep():
946
+ """
947
+ GLAD Sentinel-2 alerts per year as multiband image.
948
+ Each band is binary (1 = alert with confidence >= 2).
949
+ Coverage: Primary humid tropical forest areas of South America
950
+ from January 2019 to present.
951
+ Date encoding: days since 2019-01-01.
952
+ Includes years from 2019 onwards.
953
+ """
954
+ col = "projects/glad/S2alert"
955
+ s2alert = ee.Image(col + "/alert")
956
+ alert_date = ee.Image(col + "/alertDate")
957
+
958
+ # Confidence threshold for confirmed alerts
959
+ confirmed = s2alert.gte(2)
960
+
961
+ # Date encoding: days since 2019-01-01
962
+ # Year boundaries (days since 2019-01-01):
963
+ # 2019-01-01 = 0, 2020-01-01 = 365, 2021-01-01 = 731, 2022-01-01 = 1096
964
+ # 2023-01-01 = 1461, 2024-01-01 = 1827, 2025-01-01 = 2192, 2026-01-01 = 2557
965
+ ref_date = ee.Date("2019-01-01")
966
+
967
+ # Build multiband image with available years (data starts 2019)
968
+ start_year = 2019
969
+ end_year = CURRENT_YEAR
970
+
971
+ # Create first band (2019)
972
+ first_year = ee.Number(start_year)
973
+ first_start_days = ee.Date.fromYMD(first_year, 1, 1).difference(ref_date, "day")
974
+ first_end_days = ee.Date.fromYMD(first_year.add(1), 1, 1).difference(
975
+ ref_date, "day"
976
+ )
977
+ first_year_mask = alert_date.gte(first_start_days).And(
978
+ alert_date.lt(first_end_days)
979
+ )
980
+ first_band_name = ee.String("GLAD-S2_year_").cat(first_year.format("%d"))
981
+ first_band = (
982
+ confirmed.updateMask(first_year_mask).rename(first_band_name).selfMask()
983
+ )
984
+
985
+ # Server-side iteration to add remaining years
986
+ years = ee.List.sequence(start_year + 1, end_year)
987
+
988
+ def add_year_band(year, img_stack):
989
+ year_num = ee.Number(year)
990
+ start_days = ee.Date.fromYMD(year_num, 1, 1).difference(ref_date, "day")
991
+ end_days = ee.Date.fromYMD(year_num.add(1), 1, 1).difference(ref_date, "day")
992
+ year_mask = alert_date.gte(start_days).And(alert_date.lt(end_days))
993
+ band_name = ee.String("GLAD-S2_year_").cat(year_num.format("%d"))
994
+ year_band = confirmed.updateMask(year_mask).rename(band_name).selfMask()
995
+ return ee.Image(img_stack).addBands(year_band)
996
+
997
+ img_stack = ee.Image(years.iterate(add_year_band, first_band))
998
+
999
+ return img_stack
1000
+
1001
+
1002
+ #### disturbances combined (split into before and after 2020)
608
1003
 
609
1004
  # TMF_deg_before_2020
610
1005
  def g_tmf_deg_before_2020_prep():