BiliSakura commited on
Commit
e6f27a5
·
verified ·
1 Parent(s): b631fc1

Sync updated code and configs (no weight re-upload)

Browse files
README.md CHANGED
@@ -1,20 +1,3 @@
1
- ---
2
- license: mit
3
- language:
4
- - en
5
- tags:
6
- - remote-sensing
7
- - earth-observation
8
- - vision
9
- - feature-extraction
10
- - galileo
11
- - sentinel-1
12
- - sentinel-2
13
- - multimodal
14
- library_name: transformers
15
- pipeline_tag: feature-extraction
16
- ---
17
-
18
  # Galileo Transformers Models
19
 
20
  Self-contained HuggingFace model checkpoints for [Galileo](https://arxiv.org/abs/2502.09356).
@@ -31,6 +14,8 @@ Each checkpoint subfolder ships remote code for model, processor, and custom pip
31
 
32
  ## Usage
33
 
 
 
34
  ```python
35
  from transformers import pipeline
36
  import numpy as np
@@ -43,15 +28,15 @@ pipe = pipeline(
43
  trust_remote_code=True,
44
  )
45
 
46
- # 10-band Sentinel-2 stack (B2,B3,B4,B5,B6,B7,B8,B8A,B11,B12)
47
- s2 = np.random.randn(32, 32, 1, 10).astype(np.float32)
48
  features = pipe(s2=s2, pool=True, return_tensors=True)
49
  ```
50
 
51
  Sentinel-1 only:
52
 
53
  ```python
54
- s1 = np.random.randn(32, 32, 1, 2).astype(np.float32)
55
  features = pipe(s1=s1, pool=True, return_tensors=True)
56
  ```
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # Galileo Transformers Models
2
 
3
  Self-contained HuggingFace model checkpoints for [Galileo](https://arxiv.org/abs/2502.09356).
 
14
 
15
  ## Usage
16
 
17
+ Galileo operates on native patch grids (default **`patch_size: 8`** in `preprocessor_config.json`). Stack shapes are `(H, W, T, C)`; no fixed 224×224 resize is applied.
18
+
19
  ```python
20
  from transformers import pipeline
21
  import numpy as np
 
28
  trust_remote_code=True,
29
  )
30
 
31
+ # 10-band Sentinel-2 stack at native spatial size
32
+ s2 = np.random.randn(64, 64, 1, 10).astype(np.float32)
33
  features = pipe(s2=s2, pool=True, return_tensors=True)
34
  ```
35
 
36
  Sentinel-1 only:
37
 
38
  ```python
39
+ s1 = np.random.randn(64, 64, 1, 2).astype(np.float32)
40
  features = pipe(s1=s1, pool=True, return_tensors=True)
41
  ```
42
 
galileo-base-patch8/config.json CHANGED
@@ -43,5 +43,262 @@
43
  "AutoModel"
44
  ]
45
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
- }
 
43
  "AutoModel"
44
  ]
45
  }
46
+ },
47
+ "s1_bands": [
48
+ "VV",
49
+ "VH"
50
+ ],
51
+ "s2_bands": [
52
+ "B2",
53
+ "B3",
54
+ "B4",
55
+ "B5",
56
+ "B6",
57
+ "B7",
58
+ "B8",
59
+ "B8A",
60
+ "B11",
61
+ "B12"
62
+ ],
63
+ "era5_bands": [
64
+ "temperature_2m",
65
+ "total_precipitation_sum"
66
+ ],
67
+ "tc_bands": [
68
+ "def",
69
+ "soil",
70
+ "aet"
71
+ ],
72
+ "viirs_bands": [
73
+ "avg_rad"
74
+ ],
75
+ "srtm_bands": [
76
+ "elevation",
77
+ "slope"
78
+ ],
79
+ "dw_bands": [
80
+ "DW_water",
81
+ "DW_trees",
82
+ "DW_grass",
83
+ "DW_flooded_vegetation",
84
+ "DW_crops",
85
+ "DW_shrub_and_scrub",
86
+ "DW_built",
87
+ "DW_bare",
88
+ "DW_snow_and_ice"
89
+ ],
90
+ "wc_bands": [
91
+ "WC_temporarycrops",
92
+ "WC_maize",
93
+ "WC_wintercereals",
94
+ "WC_springcereals",
95
+ "WC_irrigation"
96
+ ],
97
+ "landscan_bands": [
98
+ "b1"
99
+ ],
100
+ "location_bands": [
101
+ "x",
102
+ "y",
103
+ "z"
104
+ ],
105
+ "space_time_band_groups": {
106
+ "S1": [
107
+ "VV",
108
+ "VH"
109
+ ],
110
+ "S2_RGB": [
111
+ "B2",
112
+ "B3",
113
+ "B4"
114
+ ],
115
+ "S2_Red_Edge": [
116
+ "B5",
117
+ "B6",
118
+ "B7"
119
+ ],
120
+ "S2_NIR_10m": [
121
+ "B8"
122
+ ],
123
+ "S2_NIR_20m": [
124
+ "B8A"
125
+ ],
126
+ "S2_SWIR": [
127
+ "B11",
128
+ "B12"
129
+ ],
130
+ "NDVI": [
131
+ "NDVI"
132
+ ]
133
+ },
134
+ "time_band_groups": {
135
+ "ERA5": [
136
+ "temperature_2m",
137
+ "total_precipitation_sum"
138
+ ],
139
+ "TC": [
140
+ "def",
141
+ "soil",
142
+ "aet"
143
+ ],
144
+ "VIIRS": [
145
+ "avg_rad"
146
+ ]
147
+ },
148
+ "space_band_groups": {
149
+ "SRTM": [
150
+ "elevation",
151
+ "slope"
152
+ ],
153
+ "DW": [
154
+ "DW_water",
155
+ "DW_trees",
156
+ "DW_grass",
157
+ "DW_flooded_vegetation",
158
+ "DW_crops",
159
+ "DW_shrub_and_scrub",
160
+ "DW_built",
161
+ "DW_bare",
162
+ "DW_snow_and_ice"
163
+ ],
164
+ "WC": [
165
+ "WC_temporarycrops",
166
+ "WC_maize",
167
+ "WC_wintercereals",
168
+ "WC_springcereals",
169
+ "WC_irrigation"
170
+ ]
171
+ },
172
+ "pretraining_normalizing_dict": {
173
+ "13": {
174
+ "mean": [
175
+ -11.728724389184965,
176
+ -18.85558188024017,
177
+ 1395.3408730676722,
178
+ 1338.4026921784578,
179
+ 1343.09883810357,
180
+ 1543.8607982512297,
181
+ 2186.2022069512263,
182
+ 2525.0932853316694,
183
+ 2410.3377187373408,
184
+ 2750.2854646886753,
185
+ 2234.911100061487,
186
+ 1474.5311266077113,
187
+ 0.2892116502999044
188
+ ],
189
+ "std": [
190
+ 4.887145774840316,
191
+ 5.730270320384293,
192
+ 917.7041440370853,
193
+ 913.2988423581528,
194
+ 1092.678723527555,
195
+ 1047.2206083460424,
196
+ 1048.0101611156767,
197
+ 1143.6903026819996,
198
+ 1098.979177731649,
199
+ 1204.472755085893,
200
+ 1145.9774063078878,
201
+ 980.2429840007796,
202
+ 0.2720939024500081
203
+ ]
204
+ },
205
+ "16": {
206
+ "mean": [
207
+ 673.0152819503361,
208
+ 5.930092668915115,
209
+ 0.10470439140978786,
210
+ 0.23965913270066183,
211
+ 0.08158044385860364,
212
+ 0.04246976254259546,
213
+ 0.11304392863520317,
214
+ 0.17329647890362473,
215
+ 0.0698981691616277,
216
+ 0.12130267132802142,
217
+ 0.04671318615236216,
218
+ 10.973119802517362,
219
+ 1.0927069179958768,
220
+ 1.6991394232855903,
221
+ 0.03720594618055555,
222
+ 1.3671352688259548
223
+ ],
224
+ "std": [
225
+ 983.0697298296237,
226
+ 8.167406789813247,
227
+ 0.18771647977504985,
228
+ 0.2368313455675914,
229
+ 0.08024268534756586,
230
+ 0.04045374496146404,
231
+ 0.11350342472061795,
232
+ 0.1279898111718168,
233
+ 0.12042341550438586,
234
+ 0.13602408145504347,
235
+ 0.043971116096060345,
236
+ 31.255340146970997,
237
+ 10.395974878206689,
238
+ 12.92380617159917,
239
+ 1.9285254295940466,
240
+ 11.612179775408928
241
+ ]
242
+ },
243
+ "6": {
244
+ "mean": [
245
+ 271.5674963541667,
246
+ 0.08554303677156568,
247
+ 657.3181260091111,
248
+ 692.1291795806885,
249
+ 562.781331880633,
250
+ 1.5647115934036673
251
+ ],
252
+ "std": [
253
+ 79.80828940314429,
254
+ 0.11669547098151486,
255
+ 704.0008695557707,
256
+ 925.0116126406431,
257
+ 453.2434022278578,
258
+ 7.513020170832818
259
+ ]
260
+ },
261
+ "18": {
262
+ "mean": [
263
+ 188.20315880851746,
264
+ 0.2804946561574936,
265
+ 0.11371652073860168,
266
+ 0.058778801321983334,
267
+ 0.10474256777763366,
268
+ 0.2396918488264084,
269
+ 0.08152248692512512,
270
+ 0.04248040814399719,
271
+ 0.11303179881572724,
272
+ 0.17326324067115784,
273
+ 0.06998309404850006,
274
+ 0.12122812910079957,
275
+ 0.04671641788482666,
276
+ 10.98456594619751,
277
+ 1.0968475807189941,
278
+ 1.6947754135131836,
279
+ 0.03320046615600586,
280
+ 1.3602827312469483
281
+ ],
282
+ "std": [
283
+ 1154.5919128300602,
284
+ 0.5276998078079327,
285
+ 0.7021637331734328,
286
+ 0.36528892213195063,
287
+ 0.17470213191865785,
288
+ 0.20411195416718833,
289
+ 0.0660782470089761,
290
+ 0.03380702424871257,
291
+ 0.09809195568521663,
292
+ 0.11292471052124119,
293
+ 0.09720748930233268,
294
+ 0.12912217763726777,
295
+ 0.0399973913151906,
296
+ 23.725471823867462,
297
+ 5.715238079725388,
298
+ 9.030481416228302,
299
+ 0.9950220242487364,
300
+ 7.754429123862099
301
+ ]
302
+ }
303
  }
304
+ }
galileo-base-patch8/modeling_galileo.py CHANGED
@@ -26,95 +26,11 @@ from einops import rearrange, repeat
26
  from torch import Tensor, vmap
27
  from torch.jit import Final
28
 
29
- # constants
30
- CONFIG_FILENAME = "config.json"
31
- ENCODER_FILENAME = "encoder.pt"
32
- BASE_GSD = 10
33
-
34
- # band information
35
- S1_BANDS = ["VV", "VH"]
36
- S2_BANDS = [
37
- "B2",
38
- "B3",
39
- "B4",
40
- "B5",
41
- "B6",
42
- "B7",
43
- "B8",
44
- "B8A",
45
- "B11",
46
- "B12",
47
- ]
48
- ERA5_BANDS = ["temperature_2m", "total_precipitation_sum"]
49
- TC_BANDS = ["def", "soil", "aet"]
50
- VIIRS_BANDS = ["avg_rad"]
51
- SRTM_BANDS = ["elevation", "slope"]
52
- DW_BANDS = [
53
- "DW_water",
54
- "DW_trees",
55
- "DW_grass",
56
- "DW_flooded_vegetation",
57
- "DW_crops",
58
- "DW_shrub_and_scrub",
59
- "DW_built",
60
- "DW_bare",
61
- "DW_snow_and_ice",
62
- ]
63
- WC_BANDS = [
64
- "WC_temporarycrops",
65
- "WC_maize",
66
- "WC_wintercereals",
67
- "WC_springcereals",
68
- "WC_irrigation",
69
- ]
70
- STATIC_DW_BANDS = [f"{x}_static" for x in DW_BANDS]
71
- STATIC_WC_BANDS = [f"{x}_static" for x in WC_BANDS]
72
-
73
- LANDSCAN_BANDS = ["b1"]
74
- LOCATION_BANDS = ["x", "y", "z"]
75
-
76
- SPACE_TIME_BANDS = S1_BANDS + S2_BANDS + ["NDVI"]
77
- TIME_BANDS = ERA5_BANDS + TC_BANDS + VIIRS_BANDS
78
- SPACE_BANDS = SRTM_BANDS + DW_BANDS + WC_BANDS
79
- STATIC_BANDS = LANDSCAN_BANDS + LOCATION_BANDS + STATIC_DW_BANDS + STATIC_WC_BANDS
80
-
81
-
82
- SPACE_TIME_BANDS_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
83
- {
84
- "S1": [SPACE_TIME_BANDS.index(b) for b in S1_BANDS],
85
- "S2_RGB": [SPACE_TIME_BANDS.index(b) for b in ["B2", "B3", "B4"]],
86
- "S2_Red_Edge": [SPACE_TIME_BANDS.index(b) for b in ["B5", "B6", "B7"]],
87
- "S2_NIR_10m": [SPACE_TIME_BANDS.index(b) for b in ["B8"]],
88
- "S2_NIR_20m": [SPACE_TIME_BANDS.index(b) for b in ["B8A"]],
89
- "S2_SWIR": [SPACE_TIME_BANDS.index(b) for b in ["B11", "B12"]],
90
- "NDVI": [SPACE_TIME_BANDS.index("NDVI")],
91
- }
92
- )
93
-
94
- TIME_BAND_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
95
- {
96
- "ERA5": [TIME_BANDS.index(b) for b in ERA5_BANDS],
97
- "TC": [TIME_BANDS.index(b) for b in TC_BANDS],
98
- "VIIRS": [TIME_BANDS.index(b) for b in VIIRS_BANDS],
99
- }
100
- )
101
 
102
- SPACE_BAND_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
103
- {
104
- "SRTM": [SPACE_BANDS.index(b) for b in SRTM_BANDS],
105
- "DW": [SPACE_BANDS.index(b) for b in DW_BANDS],
106
- "WC": [SPACE_BANDS.index(b) for b in WC_BANDS],
107
- }
108
- )
109
-
110
- STATIC_BAND_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
111
- {
112
- "LS": [STATIC_BANDS.index(b) for b in LANDSCAN_BANDS],
113
- "location": [STATIC_BANDS.index(b) for b in LOCATION_BANDS],
114
- "DW_static": [STATIC_BANDS.index(b) for b in STATIC_DW_BANDS],
115
- "WC_static": [STATIC_BANDS.index(b) for b in STATIC_WC_BANDS],
116
- }
117
- )
118
 
119
 
120
  def get_2d_sincos_pos_embed_with_resolution(
@@ -565,13 +481,16 @@ class GalileoBase(nn.Module):
565
  base_patch_size: int = 4,
566
  use_channel_embs: bool = True,
567
  drop_path: float = 0.0,
 
568
  ):
569
  super().__init__()
570
 
571
- self.space_time_groups = SPACE_TIME_BANDS_GROUPS_IDX
572
- self.space_groups = SPACE_BAND_GROUPS_IDX
573
- self.time_groups = TIME_BAND_GROUPS_IDX
574
- self.static_groups = STATIC_BAND_GROUPS_IDX
 
 
575
  self.embedding_size = embedding_size
576
  self.base_patch_size = base_patch_size
577
 
@@ -606,16 +525,16 @@ class GalileoBase(nn.Module):
606
  else:
607
  args = {"requires_grad": False}
608
  self.s_t_channel_embed = nn.Parameter(
609
- torch.zeros(len(SPACE_TIME_BANDS_GROUPS_IDX), int(embedding_size * 0.25)), **args
610
  )
611
  self.sp_channel_embed = nn.Parameter(
612
- torch.zeros(len(SPACE_BAND_GROUPS_IDX), int(embedding_size * 0.25)), **args
613
  )
614
  self.t_channel_embed = nn.Parameter(
615
- torch.zeros(len(TIME_BAND_GROUPS_IDX), int(embedding_size * 0.25)), **args
616
  )
617
  self.st_channel_embed = nn.Parameter(
618
- torch.zeros(len(STATIC_BAND_GROUPS_IDX), int(embedding_size * 0.25)), **args
619
  )
620
 
621
  self.apply(self._init_weights)
@@ -720,7 +639,7 @@ class GalileoBase(nn.Module):
720
  if patch_size is None:
721
  patch_size = self.base_patch_size
722
  token_res = input_res * patch_size
723
- gsd_ratio = token_res / BASE_GSD
724
 
725
  assert h == w, "get_2d_sincos_pos_embed_with_resolution currently requires that h==w"
726
  spatial_embed = get_2d_sincos_pos_embed_with_resolution(
@@ -755,6 +674,7 @@ class Encoder(GalileoBase):
755
  max_sequence_length=24,
756
  freeze_projections: bool = False,
757
  drop_path: float = 0.0,
 
758
  ):
759
  super().__init__(
760
  embedding_size,
@@ -765,6 +685,7 @@ class Encoder(GalileoBase):
765
  max_patch_size,
766
  use_channel_embs=True,
767
  drop_path=drop_path,
 
768
  )
769
 
770
  self.space_time_embed = nn.ModuleDict(
@@ -1108,11 +1029,14 @@ class Encoder(GalileoBase):
1108
  st_m: torch.Tensor,
1109
  months: torch.Tensor,
1110
  patch_size: int,
1111
- input_resolution_m: Optional[int] = BASE_GSD,
1112
  exit_after: Optional[int] = None,
1113
  token_exit_cfg: Optional[Dict] = None,
1114
  add_layernorm_on_exit: bool = True,
1115
  ):
 
 
 
1116
  (
1117
  s_t_x,
1118
  sp_x,
@@ -1161,25 +1085,31 @@ class Encoder(GalileoBase):
1161
  )
1162
 
1163
  @classmethod
1164
- def load_from_folder(cls, folder: Path, device: torch.device):
1165
- if not (folder / CONFIG_FILENAME).exists():
 
 
 
 
 
 
1166
  all_files_in_folder = [f.name for f in folder.glob("*")]
1167
  raise ValueError(
1168
- f"Expected {CONFIG_FILENAME} in {folder}, found {all_files_in_folder}"
1169
  )
1170
- if not (folder / ENCODER_FILENAME).exists():
1171
  all_files_in_folder = [f.name for f in folder.glob("*")]
1172
  raise ValueError(
1173
- f"Expected {ENCODER_FILENAME} in {folder}, found {all_files_in_folder}"
1174
  )
1175
 
1176
- with (folder / CONFIG_FILENAME).open("r") as f:
1177
  config = json.load(f)
1178
  model_config = config["model"]
1179
  encoder_config = model_config["encoder"]
1180
  encoder = cls(**encoder_config)
1181
 
1182
- state_dict = torch.load(folder / ENCODER_FILENAME, map_location=device)
1183
  for key in list(state_dict.keys()):
1184
  # this cleans the state dict, which occasionally had an extra
1185
  # ".backbone" included in the key names
@@ -1189,6 +1119,141 @@ class Encoder(GalileoBase):
1189
  logger = logging.get_logger(__name__)
1190
 
1191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1192
  class GalileoConfig(PreTrainedConfig):
1193
  model_type = "galileo"
1194
 
@@ -1206,6 +1271,20 @@ class GalileoConfig(PreTrainedConfig):
1206
  default_month: int = 6,
1207
  global_pool: bool = True,
1208
  input_resolution_m: int = 10,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1209
  **kwargs,
1210
  ):
1211
  super().__init__(**kwargs)
@@ -1221,6 +1300,89 @@ class GalileoConfig(PreTrainedConfig):
1221
  self.default_month = default_month
1222
  self.global_pool = global_pool
1223
  self.input_resolution_m = input_resolution_m
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1224
 
1225
 
1226
  class GalileoPreTrainedModel(PreTrainedModel):
@@ -1245,6 +1407,7 @@ class GalileoEncoderModel(GalileoPreTrainedModel):
1245
  max_sequence_length=config.max_sequence_length,
1246
  freeze_projections=config.freeze_projections,
1247
  drop_path=config.drop_path,
 
1248
  )
1249
  self.add_pooling_layer = add_pooling_layer and config.global_pool
1250
  self.post_init()
 
26
  from torch import Tensor, vmap
27
  from torch.jit import Final
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ def _band_group_indices(
31
+ bands: Sequence[str], groups: Dict[str, List[str]]
32
+ ) -> OrderedDictType[str, List[int]]:
33
+ return OrderedDict((name, [bands.index(b) for b in group_bands]) for name, group_bands in groups.items())
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
 
36
  def get_2d_sincos_pos_embed_with_resolution(
 
481
  base_patch_size: int = 4,
482
  use_channel_embs: bool = True,
483
  drop_path: float = 0.0,
484
+ band_layout: Optional[Dict[str, Any]] = None,
485
  ):
486
  super().__init__()
487
 
488
+ band_layout = band_layout or GalileoConfig().band_layout()
489
+ self.space_time_groups = band_layout["space_time_groups"]
490
+ self.space_groups = band_layout["space_groups"]
491
+ self.time_groups = band_layout["time_groups"]
492
+ self.static_groups = band_layout["static_groups"]
493
+ self.base_gsd = band_layout["input_resolution_m"]
494
  self.embedding_size = embedding_size
495
  self.base_patch_size = base_patch_size
496
 
 
525
  else:
526
  args = {"requires_grad": False}
527
  self.s_t_channel_embed = nn.Parameter(
528
+ torch.zeros(len(self.space_time_groups), int(embedding_size * 0.25)), **args
529
  )
530
  self.sp_channel_embed = nn.Parameter(
531
+ torch.zeros(len(self.space_groups), int(embedding_size * 0.25)), **args
532
  )
533
  self.t_channel_embed = nn.Parameter(
534
+ torch.zeros(len(self.time_groups), int(embedding_size * 0.25)), **args
535
  )
536
  self.st_channel_embed = nn.Parameter(
537
+ torch.zeros(len(self.static_groups), int(embedding_size * 0.25)), **args
538
  )
539
 
540
  self.apply(self._init_weights)
 
639
  if patch_size is None:
640
  patch_size = self.base_patch_size
641
  token_res = input_res * patch_size
642
+ gsd_ratio = token_res / self.base_gsd
643
 
644
  assert h == w, "get_2d_sincos_pos_embed_with_resolution currently requires that h==w"
645
  spatial_embed = get_2d_sincos_pos_embed_with_resolution(
 
674
  max_sequence_length=24,
675
  freeze_projections: bool = False,
676
  drop_path: float = 0.0,
677
+ band_layout: Optional[Dict[str, Any]] = None,
678
  ):
679
  super().__init__(
680
  embedding_size,
 
685
  max_patch_size,
686
  use_channel_embs=True,
687
  drop_path=drop_path,
688
+ band_layout=band_layout,
689
  )
690
 
691
  self.space_time_embed = nn.ModuleDict(
 
1029
  st_m: torch.Tensor,
1030
  months: torch.Tensor,
1031
  patch_size: int,
1032
+ input_resolution_m: Optional[int] = None,
1033
  exit_after: Optional[int] = None,
1034
  token_exit_cfg: Optional[Dict] = None,
1035
  add_layernorm_on_exit: bool = True,
1036
  ):
1037
+ if input_resolution_m is None:
1038
+ input_resolution_m = self.base_gsd
1039
+
1040
  (
1041
  s_t_x,
1042
  sp_x,
 
1085
  )
1086
 
1087
  @classmethod
1088
+ def load_from_folder(
1089
+ cls,
1090
+ folder: Path,
1091
+ device: torch.device,
1092
+ config_filename: str = "config.json",
1093
+ encoder_filename: str = "encoder.pt",
1094
+ ):
1095
+ if not (folder / config_filename).exists():
1096
  all_files_in_folder = [f.name for f in folder.glob("*")]
1097
  raise ValueError(
1098
+ f"Expected {config_filename} in {folder}, found {all_files_in_folder}"
1099
  )
1100
+ if not (folder / encoder_filename).exists():
1101
  all_files_in_folder = [f.name for f in folder.glob("*")]
1102
  raise ValueError(
1103
+ f"Expected {encoder_filename} in {folder}, found {all_files_in_folder}"
1104
  )
1105
 
1106
+ with (folder / config_filename).open("r") as f:
1107
  config = json.load(f)
1108
  model_config = config["model"]
1109
  encoder_config = model_config["encoder"]
1110
  encoder = cls(**encoder_config)
1111
 
1112
+ state_dict = torch.load(folder / encoder_filename, map_location=device)
1113
  for key in list(state_dict.keys()):
1114
  # this cleans the state dict, which occasionally had an extra
1115
  # ".backbone" included in the key names
 
1119
  logger = logging.get_logger(__name__)
1120
 
1121
 
1122
+ def _default_pretraining_normalizing_dict() -> Dict[str, Dict[str, List[float]]]:
1123
+ return {
1124
+ "13": {
1125
+ "mean": [
1126
+ -11.728724389184965,
1127
+ -18.85558188024017,
1128
+ 1395.3408730676722,
1129
+ 1338.4026921784578,
1130
+ 1343.09883810357,
1131
+ 1543.8607982512297,
1132
+ 2186.2022069512263,
1133
+ 2525.0932853316694,
1134
+ 2410.3377187373408,
1135
+ 2750.2854646886753,
1136
+ 2234.911100061487,
1137
+ 1474.5311266077113,
1138
+ 0.2892116502999044,
1139
+ ],
1140
+ "std": [
1141
+ 4.887145774840316,
1142
+ 5.730270320384293,
1143
+ 917.7041440370853,
1144
+ 913.2988423581528,
1145
+ 1092.678723527555,
1146
+ 1047.2206083460424,
1147
+ 1048.0101611156767,
1148
+ 1143.6903026819996,
1149
+ 1098.979177731649,
1150
+ 1204.472755085893,
1151
+ 1145.9774063078878,
1152
+ 980.2429840007796,
1153
+ 0.2720939024500081,
1154
+ ],
1155
+ },
1156
+ "16": {
1157
+ "mean": [
1158
+ 673.0152819503361,
1159
+ 5.930092668915115,
1160
+ 0.10470439140978786,
1161
+ 0.23965913270066183,
1162
+ 0.08158044385860364,
1163
+ 0.04246976254259546,
1164
+ 0.11304392863520317,
1165
+ 0.17329647890362473,
1166
+ 0.0698981691616277,
1167
+ 0.12130267132802142,
1168
+ 0.04671318615236216,
1169
+ 10.973119802517362,
1170
+ 1.0927069179958768,
1171
+ 1.6991394232855903,
1172
+ 0.03720594618055555,
1173
+ 1.3671352688259548,
1174
+ ],
1175
+ "std": [
1176
+ 983.0697298296237,
1177
+ 8.167406789813247,
1178
+ 0.18771647977504985,
1179
+ 0.2368313455675914,
1180
+ 0.08024268534756586,
1181
+ 0.04045374496146404,
1182
+ 0.11350342472061795,
1183
+ 0.1279898111718168,
1184
+ 0.12042341550438586,
1185
+ 0.13602408145504347,
1186
+ 0.043971116096060345,
1187
+ 31.255340146970997,
1188
+ 10.395974878206689,
1189
+ 12.92380617159917,
1190
+ 1.9285254295940466,
1191
+ 11.612179775408928,
1192
+ ],
1193
+ },
1194
+ "6": {
1195
+ "mean": [
1196
+ 271.5674963541667,
1197
+ 0.08554303677156568,
1198
+ 657.3181260091111,
1199
+ 692.1291795806885,
1200
+ 562.781331880633,
1201
+ 1.5647115934036673,
1202
+ ],
1203
+ "std": [
1204
+ 79.80828940314429,
1205
+ 0.11669547098151486,
1206
+ 704.0008695557707,
1207
+ 925.0116126406431,
1208
+ 453.2434022278578,
1209
+ 7.513020170832818,
1210
+ ],
1211
+ },
1212
+ "18": {
1213
+ "mean": [
1214
+ 188.20315880851746,
1215
+ 0.2804946561574936,
1216
+ 0.11371652073860168,
1217
+ 0.058778801321983334,
1218
+ 0.10474256777763366,
1219
+ 0.2396918488264084,
1220
+ 0.08152248692512512,
1221
+ 0.04248040814399719,
1222
+ 0.11303179881572724,
1223
+ 0.17326324067115784,
1224
+ 0.06998309404850006,
1225
+ 0.12122812910079957,
1226
+ 0.04671641788482666,
1227
+ 10.98456594619751,
1228
+ 1.0968475807189941,
1229
+ 1.6947754135131836,
1230
+ 0.03320046615600586,
1231
+ 1.3602827312469483,
1232
+ ],
1233
+ "std": [
1234
+ 1154.5919128300602,
1235
+ 0.5276998078079327,
1236
+ 0.7021637331734328,
1237
+ 0.36528892213195063,
1238
+ 0.17470213191865785,
1239
+ 0.20411195416718833,
1240
+ 0.0660782470089761,
1241
+ 0.03380702424871257,
1242
+ 0.09809195568521663,
1243
+ 0.11292471052124119,
1244
+ 0.09720748930233268,
1245
+ 0.12912217763726777,
1246
+ 0.0399973913151906,
1247
+ 23.725471823867462,
1248
+ 5.715238079725388,
1249
+ 9.030481416228302,
1250
+ 0.9950220242487364,
1251
+ 7.754429123862099,
1252
+ ],
1253
+ },
1254
+ }
1255
+
1256
+
1257
  class GalileoConfig(PreTrainedConfig):
1258
  model_type = "galileo"
1259
 
 
1271
  default_month: int = 6,
1272
  global_pool: bool = True,
1273
  input_resolution_m: int = 10,
1274
+ s1_bands: Optional[List[str]] = None,
1275
+ s2_bands: Optional[List[str]] = None,
1276
+ era5_bands: Optional[List[str]] = None,
1277
+ tc_bands: Optional[List[str]] = None,
1278
+ viirs_bands: Optional[List[str]] = None,
1279
+ srtm_bands: Optional[List[str]] = None,
1280
+ dw_bands: Optional[List[str]] = None,
1281
+ wc_bands: Optional[List[str]] = None,
1282
+ landscan_bands: Optional[List[str]] = None,
1283
+ location_bands: Optional[List[str]] = None,
1284
+ space_time_band_groups: Optional[Dict[str, List[str]]] = None,
1285
+ time_band_groups: Optional[Dict[str, List[str]]] = None,
1286
+ space_band_groups: Optional[Dict[str, List[str]]] = None,
1287
+ pretraining_normalizing_dict: Optional[Dict[str, Dict[str, List[float]]]] = None,
1288
  **kwargs,
1289
  ):
1290
  super().__init__(**kwargs)
 
1300
  self.default_month = default_month
1301
  self.global_pool = global_pool
1302
  self.input_resolution_m = input_resolution_m
1303
+ self.s1_bands = s1_bands if s1_bands is not None else ["VV", "VH"]
1304
+ self.s2_bands = s2_bands if s2_bands is not None else [
1305
+ "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B8A", "B11", "B12",
1306
+ ]
1307
+ self.era5_bands = era5_bands if era5_bands is not None else [
1308
+ "temperature_2m", "total_precipitation_sum",
1309
+ ]
1310
+ self.tc_bands = tc_bands if tc_bands is not None else ["def", "soil", "aet"]
1311
+ self.viirs_bands = viirs_bands if viirs_bands is not None else ["avg_rad"]
1312
+ self.srtm_bands = srtm_bands if srtm_bands is not None else ["elevation", "slope"]
1313
+ self.dw_bands = dw_bands if dw_bands is not None else [
1314
+ "DW_water", "DW_trees", "DW_grass", "DW_flooded_vegetation", "DW_crops",
1315
+ "DW_shrub_and_scrub", "DW_built", "DW_bare", "DW_snow_and_ice",
1316
+ ]
1317
+ self.wc_bands = wc_bands if wc_bands is not None else [
1318
+ "WC_temporarycrops", "WC_maize", "WC_wintercereals", "WC_springcereals", "WC_irrigation",
1319
+ ]
1320
+ self.landscan_bands = landscan_bands if landscan_bands is not None else ["b1"]
1321
+ self.location_bands = location_bands if location_bands is not None else ["x", "y", "z"]
1322
+ self.space_time_band_groups = space_time_band_groups if space_time_band_groups is not None else {
1323
+ "S1": ["VV", "VH"],
1324
+ "S2_RGB": ["B2", "B3", "B4"],
1325
+ "S2_Red_Edge": ["B5", "B6", "B7"],
1326
+ "S2_NIR_10m": ["B8"],
1327
+ "S2_NIR_20m": ["B8A"],
1328
+ "S2_SWIR": ["B11", "B12"],
1329
+ "NDVI": ["NDVI"],
1330
+ }
1331
+ self.time_band_groups = time_band_groups if time_band_groups is not None else {
1332
+ "ERA5": ["temperature_2m", "total_precipitation_sum"],
1333
+ "TC": ["def", "soil", "aet"],
1334
+ "VIIRS": ["avg_rad"],
1335
+ }
1336
+ self.space_band_groups = space_band_groups if space_band_groups is not None else {
1337
+ "SRTM": ["elevation", "slope"],
1338
+ "DW": [
1339
+ "DW_water", "DW_trees", "DW_grass", "DW_flooded_vegetation", "DW_crops",
1340
+ "DW_shrub_and_scrub", "DW_built", "DW_bare", "DW_snow_and_ice",
1341
+ ],
1342
+ "WC": [
1343
+ "WC_temporarycrops", "WC_maize", "WC_wintercereals", "WC_springcereals", "WC_irrigation",
1344
+ ],
1345
+ }
1346
+ self.pretraining_normalizing_dict = (
1347
+ pretraining_normalizing_dict
1348
+ if pretraining_normalizing_dict is not None
1349
+ else _default_pretraining_normalizing_dict()
1350
+ )
1351
+
1352
+ def band_layout(self) -> Dict[str, Any]:
1353
+ space_time_bands = self.s1_bands + self.s2_bands + ["NDVI"]
1354
+ time_bands = self.era5_bands + self.tc_bands + self.viirs_bands
1355
+ space_bands = self.srtm_bands + self.dw_bands + self.wc_bands
1356
+ static_dw_bands = [f"{band}_static" for band in self.dw_bands]
1357
+ static_wc_bands = [f"{band}_static" for band in self.wc_bands]
1358
+ static_bands = self.landscan_bands + self.location_bands + static_dw_bands + static_wc_bands
1359
+ static_band_groups = {
1360
+ "LS": self.landscan_bands,
1361
+ "location": self.location_bands,
1362
+ "DW_static": static_dw_bands,
1363
+ "WC_static": static_wc_bands,
1364
+ }
1365
+ return {
1366
+ "s1_bands": self.s1_bands,
1367
+ "s2_bands": self.s2_bands,
1368
+ "era5_bands": self.era5_bands,
1369
+ "tc_bands": self.tc_bands,
1370
+ "viirs_bands": self.viirs_bands,
1371
+ "srtm_bands": self.srtm_bands,
1372
+ "dw_bands": self.dw_bands,
1373
+ "wc_bands": self.wc_bands,
1374
+ "landscan_bands": self.landscan_bands,
1375
+ "location_bands": self.location_bands,
1376
+ "space_time_bands": space_time_bands,
1377
+ "time_bands": time_bands,
1378
+ "space_bands": space_bands,
1379
+ "static_bands": static_bands,
1380
+ "space_time_groups": _band_group_indices(space_time_bands, self.space_time_band_groups),
1381
+ "time_groups": _band_group_indices(time_bands, self.time_band_groups),
1382
+ "space_groups": _band_group_indices(space_bands, self.space_band_groups),
1383
+ "static_groups": _band_group_indices(static_bands, static_band_groups),
1384
+ "input_resolution_m": self.input_resolution_m,
1385
+ }
1386
 
1387
 
1388
  class GalileoPreTrainedModel(PreTrainedModel):
 
1407
  max_sequence_length=config.max_sequence_length,
1408
  freeze_projections=config.freeze_projections,
1409
  drop_path=config.drop_path,
1410
+ band_layout=config.band_layout(),
1411
  )
1412
  self.add_pooling_layer = add_pooling_layer and config.global_pool
1413
  self.post_init()
galileo-base-patch8/preprocessor_config.json CHANGED
@@ -5,5 +5,262 @@
5
  "patch_size": 8,
6
  "auto_map": {
7
  "AutoProcessor": "processing_galileo.GalileoProcessor"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  }
9
- }
 
5
  "patch_size": 8,
6
  "auto_map": {
7
  "AutoProcessor": "processing_galileo.GalileoProcessor"
8
+ },
9
+ "s1_bands": [
10
+ "VV",
11
+ "VH"
12
+ ],
13
+ "s2_bands": [
14
+ "B2",
15
+ "B3",
16
+ "B4",
17
+ "B5",
18
+ "B6",
19
+ "B7",
20
+ "B8",
21
+ "B8A",
22
+ "B11",
23
+ "B12"
24
+ ],
25
+ "era5_bands": [
26
+ "temperature_2m",
27
+ "total_precipitation_sum"
28
+ ],
29
+ "tc_bands": [
30
+ "def",
31
+ "soil",
32
+ "aet"
33
+ ],
34
+ "viirs_bands": [
35
+ "avg_rad"
36
+ ],
37
+ "srtm_bands": [
38
+ "elevation",
39
+ "slope"
40
+ ],
41
+ "dw_bands": [
42
+ "DW_water",
43
+ "DW_trees",
44
+ "DW_grass",
45
+ "DW_flooded_vegetation",
46
+ "DW_crops",
47
+ "DW_shrub_and_scrub",
48
+ "DW_built",
49
+ "DW_bare",
50
+ "DW_snow_and_ice"
51
+ ],
52
+ "wc_bands": [
53
+ "WC_temporarycrops",
54
+ "WC_maize",
55
+ "WC_wintercereals",
56
+ "WC_springcereals",
57
+ "WC_irrigation"
58
+ ],
59
+ "landscan_bands": [
60
+ "b1"
61
+ ],
62
+ "location_bands": [
63
+ "x",
64
+ "y",
65
+ "z"
66
+ ],
67
+ "space_time_band_groups": {
68
+ "S1": [
69
+ "VV",
70
+ "VH"
71
+ ],
72
+ "S2_RGB": [
73
+ "B2",
74
+ "B3",
75
+ "B4"
76
+ ],
77
+ "S2_Red_Edge": [
78
+ "B5",
79
+ "B6",
80
+ "B7"
81
+ ],
82
+ "S2_NIR_10m": [
83
+ "B8"
84
+ ],
85
+ "S2_NIR_20m": [
86
+ "B8A"
87
+ ],
88
+ "S2_SWIR": [
89
+ "B11",
90
+ "B12"
91
+ ],
92
+ "NDVI": [
93
+ "NDVI"
94
+ ]
95
+ },
96
+ "time_band_groups": {
97
+ "ERA5": [
98
+ "temperature_2m",
99
+ "total_precipitation_sum"
100
+ ],
101
+ "TC": [
102
+ "def",
103
+ "soil",
104
+ "aet"
105
+ ],
106
+ "VIIRS": [
107
+ "avg_rad"
108
+ ]
109
+ },
110
+ "space_band_groups": {
111
+ "SRTM": [
112
+ "elevation",
113
+ "slope"
114
+ ],
115
+ "DW": [
116
+ "DW_water",
117
+ "DW_trees",
118
+ "DW_grass",
119
+ "DW_flooded_vegetation",
120
+ "DW_crops",
121
+ "DW_shrub_and_scrub",
122
+ "DW_built",
123
+ "DW_bare",
124
+ "DW_snow_and_ice"
125
+ ],
126
+ "WC": [
127
+ "WC_temporarycrops",
128
+ "WC_maize",
129
+ "WC_wintercereals",
130
+ "WC_springcereals",
131
+ "WC_irrigation"
132
+ ]
133
+ },
134
+ "pretraining_normalizing_dict": {
135
+ "13": {
136
+ "mean": [
137
+ -11.728724389184965,
138
+ -18.85558188024017,
139
+ 1395.3408730676722,
140
+ 1338.4026921784578,
141
+ 1343.09883810357,
142
+ 1543.8607982512297,
143
+ 2186.2022069512263,
144
+ 2525.0932853316694,
145
+ 2410.3377187373408,
146
+ 2750.2854646886753,
147
+ 2234.911100061487,
148
+ 1474.5311266077113,
149
+ 0.2892116502999044
150
+ ],
151
+ "std": [
152
+ 4.887145774840316,
153
+ 5.730270320384293,
154
+ 917.7041440370853,
155
+ 913.2988423581528,
156
+ 1092.678723527555,
157
+ 1047.2206083460424,
158
+ 1048.0101611156767,
159
+ 1143.6903026819996,
160
+ 1098.979177731649,
161
+ 1204.472755085893,
162
+ 1145.9774063078878,
163
+ 980.2429840007796,
164
+ 0.2720939024500081
165
+ ]
166
+ },
167
+ "16": {
168
+ "mean": [
169
+ 673.0152819503361,
170
+ 5.930092668915115,
171
+ 0.10470439140978786,
172
+ 0.23965913270066183,
173
+ 0.08158044385860364,
174
+ 0.04246976254259546,
175
+ 0.11304392863520317,
176
+ 0.17329647890362473,
177
+ 0.0698981691616277,
178
+ 0.12130267132802142,
179
+ 0.04671318615236216,
180
+ 10.973119802517362,
181
+ 1.0927069179958768,
182
+ 1.6991394232855903,
183
+ 0.03720594618055555,
184
+ 1.3671352688259548
185
+ ],
186
+ "std": [
187
+ 983.0697298296237,
188
+ 8.167406789813247,
189
+ 0.18771647977504985,
190
+ 0.2368313455675914,
191
+ 0.08024268534756586,
192
+ 0.04045374496146404,
193
+ 0.11350342472061795,
194
+ 0.1279898111718168,
195
+ 0.12042341550438586,
196
+ 0.13602408145504347,
197
+ 0.043971116096060345,
198
+ 31.255340146970997,
199
+ 10.395974878206689,
200
+ 12.92380617159917,
201
+ 1.9285254295940466,
202
+ 11.612179775408928
203
+ ]
204
+ },
205
+ "6": {
206
+ "mean": [
207
+ 271.5674963541667,
208
+ 0.08554303677156568,
209
+ 657.3181260091111,
210
+ 692.1291795806885,
211
+ 562.781331880633,
212
+ 1.5647115934036673
213
+ ],
214
+ "std": [
215
+ 79.80828940314429,
216
+ 0.11669547098151486,
217
+ 704.0008695557707,
218
+ 925.0116126406431,
219
+ 453.2434022278578,
220
+ 7.513020170832818
221
+ ]
222
+ },
223
+ "18": {
224
+ "mean": [
225
+ 188.20315880851746,
226
+ 0.2804946561574936,
227
+ 0.11371652073860168,
228
+ 0.058778801321983334,
229
+ 0.10474256777763366,
230
+ 0.2396918488264084,
231
+ 0.08152248692512512,
232
+ 0.04248040814399719,
233
+ 0.11303179881572724,
234
+ 0.17326324067115784,
235
+ 0.06998309404850006,
236
+ 0.12122812910079957,
237
+ 0.04671641788482666,
238
+ 10.98456594619751,
239
+ 1.0968475807189941,
240
+ 1.6947754135131836,
241
+ 0.03320046615600586,
242
+ 1.3602827312469483
243
+ ],
244
+ "std": [
245
+ 1154.5919128300602,
246
+ 0.5276998078079327,
247
+ 0.7021637331734328,
248
+ 0.36528892213195063,
249
+ 0.17470213191865785,
250
+ 0.20411195416718833,
251
+ 0.0660782470089761,
252
+ 0.03380702424871257,
253
+ 0.09809195568521663,
254
+ 0.11292471052124119,
255
+ 0.09720748930233268,
256
+ 0.12912217763726777,
257
+ 0.0399973913151906,
258
+ 23.725471823867462,
259
+ 5.715238079725388,
260
+ 9.030481416228302,
261
+ 0.9950220242487364,
262
+ 7.754429123862099
263
+ ]
264
+ }
265
  }
266
+ }
galileo-base-patch8/processing_galileo.py CHANGED
@@ -4,7 +4,6 @@
4
  from __future__ import annotations
5
 
6
  import math
7
- from collections import OrderedDict
8
  from typing import Any, NamedTuple, Optional, Union
9
 
10
  import numpy as np
@@ -14,191 +13,7 @@ from transformers.feature_extraction_utils import BatchFeature
14
  from transformers.processing_utils import ProcessorMixin
15
  from transformers.utils import TensorType
16
 
17
-
18
- S1_BANDS = ["VV", "VH"]
19
- S2_BANDS = ["B2", "B3", "B4", "B5", "B6", "B7", "B8", "B8A", "B11", "B12"]
20
- ERA5_BANDS = ["temperature_2m", "total_precipitation_sum"]
21
- TC_BANDS = ["def", "soil", "aet"]
22
- VIIRS_BANDS = ["avg_rad"]
23
- SRTM_BANDS = ["elevation", "slope"]
24
- DW_BANDS = [
25
- "DW_water", "DW_trees", "DW_grass", "DW_flooded_vegetation", "DW_crops",
26
- "DW_shrub_and_scrub", "DW_built", "DW_bare", "DW_snow_and_ice",
27
- ]
28
- WC_BANDS = [
29
- "WC_temporarycrops", "WC_maize", "WC_wintercereals", "WC_springcereals", "WC_irrigation",
30
- ]
31
- LANDSCAN_BANDS = ["b1"]
32
- LOCATION_BANDS = ["x", "y", "z"]
33
- STATIC_DW_BANDS = [f"{x}_static" for x in DW_BANDS]
34
- STATIC_WC_BANDS = [f"{x}_static" for x in WC_BANDS]
35
-
36
- SPACE_TIME_BANDS = S1_BANDS + S2_BANDS + ["NDVI"]
37
- TIME_BANDS = ERA5_BANDS + TC_BANDS + VIIRS_BANDS
38
- SPACE_BANDS = SRTM_BANDS + DW_BANDS + WC_BANDS
39
- STATIC_BANDS = LANDSCAN_BANDS + LOCATION_BANDS + STATIC_DW_BANDS + STATIC_WC_BANDS
40
-
41
- SPACE_TIME_BANDS_GROUPS_IDX = OrderedDict({
42
- "S1": [SPACE_TIME_BANDS.index(b) for b in S1_BANDS],
43
- "S2_RGB": [SPACE_TIME_BANDS.index(b) for b in ["B2", "B3", "B4"]],
44
- "S2_Red_Edge": [SPACE_TIME_BANDS.index(b) for b in ["B5", "B6", "B7"]],
45
- "S2_NIR_10m": [SPACE_TIME_BANDS.index(b) for b in ["B8"]],
46
- "S2_NIR_20m": [SPACE_TIME_BANDS.index(b) for b in ["B8A"]],
47
- "S2_SWIR": [SPACE_TIME_BANDS.index(b) for b in ["B11", "B12"]],
48
- "NDVI": [SPACE_TIME_BANDS.index("NDVI")],
49
- })
50
- TIME_BAND_GROUPS_IDX = OrderedDict({
51
- "ERA5": [TIME_BANDS.index(b) for b in ERA5_BANDS],
52
- "TC": [TIME_BANDS.index(b) for b in TC_BANDS],
53
- "VIIRS": [TIME_BANDS.index(b) for b in VIIRS_BANDS],
54
- })
55
- SPACE_BAND_GROUPS_IDX = OrderedDict({
56
- "SRTM": [SPACE_BANDS.index(b) for b in SRTM_BANDS],
57
- "DW": [SPACE_BANDS.index(b) for b in DW_BANDS],
58
- "WC": [SPACE_BANDS.index(b) for b in WC_BANDS],
59
- })
60
- STATIC_BAND_GROUPS_IDX = OrderedDict({
61
- "LS": [STATIC_BANDS.index(b) for b in LANDSCAN_BANDS],
62
- "location": [STATIC_BANDS.index(b) for b in LOCATION_BANDS],
63
- "DW_static": [STATIC_BANDS.index(b) for b in STATIC_DW_BANDS],
64
- "WC_static": [STATIC_BANDS.index(b) for b in STATIC_WC_BANDS],
65
- })
66
-
67
-
68
- DEFAULT_MONTH = 5
69
-
70
- PRETRAINING_NORMALIZING_DICT = {
71
- "13": {
72
- "mean": [
73
- -11.728724389184965,
74
- -18.85558188024017,
75
- 1395.3408730676722,
76
- 1338.4026921784578,
77
- 1343.09883810357,
78
- 1543.8607982512297,
79
- 2186.2022069512263,
80
- 2525.0932853316694,
81
- 2410.3377187373408,
82
- 2750.2854646886753,
83
- 2234.911100061487,
84
- 1474.5311266077113,
85
- 0.2892116502999044,
86
- ],
87
- "std": [
88
- 4.887145774840316,
89
- 5.730270320384293,
90
- 917.7041440370853,
91
- 913.2988423581528,
92
- 1092.678723527555,
93
- 1047.2206083460424,
94
- 1048.0101611156767,
95
- 1143.6903026819996,
96
- 1098.979177731649,
97
- 1204.472755085893,
98
- 1145.9774063078878,
99
- 980.2429840007796,
100
- 0.2720939024500081,
101
- ],
102
- },
103
- "16": {
104
- "mean": [
105
- 673.0152819503361,
106
- 5.930092668915115,
107
- 0.10470439140978786,
108
- 0.23965913270066183,
109
- 0.08158044385860364,
110
- 0.04246976254259546,
111
- 0.11304392863520317,
112
- 0.17329647890362473,
113
- 0.0698981691616277,
114
- 0.12130267132802142,
115
- 0.04671318615236216,
116
- 10.973119802517362,
117
- 1.0927069179958768,
118
- 1.6991394232855903,
119
- 0.03720594618055555,
120
- 1.3671352688259548,
121
- ],
122
- "std": [
123
- 983.0697298296237,
124
- 8.167406789813247,
125
- 0.18771647977504985,
126
- 0.2368313455675914,
127
- 0.08024268534756586,
128
- 0.04045374496146404,
129
- 0.11350342472061795,
130
- 0.1279898111718168,
131
- 0.12042341550438586,
132
- 0.13602408145504347,
133
- 0.043971116096060345,
134
- 31.255340146970997,
135
- 10.395974878206689,
136
- 12.92380617159917,
137
- 1.9285254295940466,
138
- 11.612179775408928,
139
- ],
140
- },
141
- "6": {
142
- "mean": [
143
- 271.5674963541667,
144
- 0.08554303677156568,
145
- 657.3181260091111,
146
- 692.1291795806885,
147
- 562.781331880633,
148
- 1.5647115934036673,
149
- ],
150
- "std": [
151
- 79.80828940314429,
152
- 0.11669547098151486,
153
- 704.0008695557707,
154
- 925.0116126406431,
155
- 453.2434022278578,
156
- 7.513020170832818,
157
- ],
158
- },
159
- "18": {
160
- "mean": [
161
- 188.20315880851746,
162
- 0.2804946561574936,
163
- 0.11371652073860168,
164
- 0.058778801321983334,
165
- 0.10474256777763366,
166
- 0.2396918488264084,
167
- 0.08152248692512512,
168
- 0.04248040814399719,
169
- 0.11303179881572724,
170
- 0.17326324067115784,
171
- 0.06998309404850006,
172
- 0.12122812910079957,
173
- 0.04671641788482666,
174
- 10.98456594619751,
175
- 1.0968475807189941,
176
- 1.6947754135131836,
177
- 0.03320046615600586,
178
- 1.3602827312469483,
179
- ],
180
- "std": [
181
- 1154.5919128300602,
182
- 0.5276998078079327,
183
- 0.7021637331734328,
184
- 0.36528892213195063,
185
- 0.17470213191865785,
186
- 0.20411195416718833,
187
- 0.0660782470089761,
188
- 0.03380702424871257,
189
- 0.09809195568521663,
190
- 0.11292471052124119,
191
- 0.09720748930233268,
192
- 0.12912217763726777,
193
- 0.0399973913151906,
194
- 23.725471823867462,
195
- 5.715238079725388,
196
- 9.030481416228302,
197
- 0.9950220242487364,
198
- 7.754429123862099,
199
- ],
200
- },
201
- }
202
 
203
 
204
  class MaskedOutput(NamedTuple):
@@ -257,7 +72,19 @@ def construct_galileo_input(
257
  latlon: torch.Tensor | None = None,
258
  months: torch.Tensor | None = None,
259
  normalize: bool = False,
 
260
  ) -> MaskedOutput:
 
 
 
 
 
 
 
 
 
 
 
261
  space_time_inputs = [s1, s2]
262
  time_inputs = [era5, tc, viirs]
263
  space_inputs = [srtm, dw, wc]
@@ -285,56 +112,56 @@ def construct_galileo_input(
285
  t = timesteps_list[0] if timesteps_list else 1
286
  h, w = (height_list[0], width_list[0]) if height_list else (1, 1)
287
 
288
- s_t_x = torch.zeros((h, w, t, len(SPACE_TIME_BANDS)), dtype=torch.float, device=device)
289
- s_t_m = torch.ones((h, w, t, len(SPACE_TIME_BANDS_GROUPS_IDX)), dtype=torch.float, device=device)
290
- sp_x = torch.zeros((h, w, len(SPACE_BANDS)), dtype=torch.float, device=device)
291
- sp_m = torch.ones((h, w, len(SPACE_BAND_GROUPS_IDX)), dtype=torch.float, device=device)
292
- t_x = torch.zeros((t, len(TIME_BANDS)), dtype=torch.float, device=device)
293
- t_m = torch.ones((t, len(TIME_BAND_GROUPS_IDX)), dtype=torch.float, device=device)
294
- st_x = torch.zeros((len(STATIC_BANDS)), dtype=torch.float, device=device)
295
- st_m = torch.ones((len(STATIC_BAND_GROUPS_IDX)), dtype=torch.float, device=device)
296
 
297
- for x, bands_list, group_key in zip([s1, s2], [S1_BANDS, S2_BANDS], ["S1", "S2"]):
298
  if x is not None:
299
- indices = [idx for idx, val in enumerate(SPACE_TIME_BANDS) if val in bands_list]
300
- groups_idx = [idx for idx, key in enumerate(SPACE_TIME_BANDS_GROUPS_IDX) if group_key in key]
301
  s_t_x[:, :, :, indices] = x
302
  s_t_m[:, :, :, groups_idx] = 0
303
 
304
  for x, bands_list, group_key in zip(
305
- [srtm, dw, wc], [SRTM_BANDS, DW_BANDS, WC_BANDS], ["SRTM", "DW", "WC"]
306
  ):
307
  if x is not None:
308
- indices = [idx for idx, val in enumerate(SPACE_BANDS) if val in bands_list]
309
- groups_idx = [idx for idx, key in enumerate(SPACE_BAND_GROUPS_IDX) if group_key in key]
310
  sp_x[:, :, indices] = x
311
  sp_m[:, :, groups_idx] = 0
312
 
313
  for x, bands_list, group_key in zip(
314
- [era5, tc, viirs], [ERA5_BANDS, TC_BANDS, VIIRS_BANDS], ["ERA5", "TC", "VIIRS"]
315
  ):
316
  if x is not None:
317
- indices = [idx for idx, val in enumerate(TIME_BANDS) if val in bands_list]
318
- groups_idx = [idx for idx, key in enumerate(TIME_BAND_GROUPS_IDX) if group_key in key]
319
  t_x[:, indices] = x
320
  t_m[:, groups_idx] = 0
321
 
322
  for x, bands_list, group_key in zip(
323
- [landscan, latlon], [LANDSCAN_BANDS, LOCATION_BANDS], ["LS", "location"]
324
  ):
325
  if x is not None:
326
  if group_key == "location":
327
  x = torch.as_tensor(to_cartesian(float(x[0]), float(x[1])), device=device)
328
- indices = [idx for idx, val in enumerate(STATIC_BANDS) if val in bands_list]
329
- groups_idx = [idx for idx, key in enumerate(STATIC_BAND_GROUPS_IDX) if group_key in key]
330
  st_x[indices] = x
331
  st_m[groups_idx] = 0
332
 
333
  if months is None:
334
- months = torch.ones((t), dtype=torch.long, device=device) * DEFAULT_MONTH
335
 
336
  if normalize:
337
- normalizer = PretrainingNormalizer(PRETRAINING_NORMALIZING_DICT)
338
  s_t_x = torch.from_numpy(normalizer(s_t_x.cpu().numpy())).to(device)
339
  sp_x = torch.from_numpy(normalizer(sp_x.cpu().numpy())).to(device)
340
  t_x = torch.from_numpy(normalizer(t_x.cpu().numpy())).to(device)
@@ -367,11 +194,48 @@ class GalileoProcessor(ProcessorMixin):
367
  "months",
368
  ]
369
 
370
- def __init__(self, normalize: bool = True, default_month: int = 6, patch_size: int = 8, **kwargs):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  super().__init__(**kwargs)
372
  self.normalize = normalize
373
  self.default_month = default_month
374
  self.patch_size = patch_size
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
 
376
  def __call__(
377
  self,
@@ -418,6 +282,7 @@ class GalileoProcessor(ProcessorMixin):
418
  latlon=_to_tensor(latlon),
419
  months=months,
420
  normalize=normalize,
 
421
  )
422
 
423
  if masked_output.space_time_x.dim() == 4:
 
4
  from __future__ import annotations
5
 
6
  import math
 
7
  from typing import Any, NamedTuple, Optional, Union
8
 
9
  import numpy as np
 
13
  from transformers.processing_utils import ProcessorMixin
14
  from transformers.utils import TensorType
15
 
16
+ from .modeling_galileo import GalileoConfig
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
 
19
  class MaskedOutput(NamedTuple):
 
72
  latlon: torch.Tensor | None = None,
73
  months: torch.Tensor | None = None,
74
  normalize: bool = False,
75
+ band_config: GalileoConfig | None = None,
76
  ) -> MaskedOutput:
77
+ band_config = band_config or GalileoConfig()
78
+ bands = band_config.band_layout()
79
+ space_time_bands = bands["space_time_bands"]
80
+ space_time_groups = bands["space_time_groups"]
81
+ time_bands = bands["time_bands"]
82
+ time_groups = bands["time_groups"]
83
+ space_bands = bands["space_bands"]
84
+ space_groups = bands["space_groups"]
85
+ static_bands = bands["static_bands"]
86
+ static_groups = bands["static_groups"]
87
+
88
  space_time_inputs = [s1, s2]
89
  time_inputs = [era5, tc, viirs]
90
  space_inputs = [srtm, dw, wc]
 
112
  t = timesteps_list[0] if timesteps_list else 1
113
  h, w = (height_list[0], width_list[0]) if height_list else (1, 1)
114
 
115
+ s_t_x = torch.zeros((h, w, t, len(space_time_bands)), dtype=torch.float, device=device)
116
+ s_t_m = torch.ones((h, w, t, len(space_time_groups)), dtype=torch.float, device=device)
117
+ sp_x = torch.zeros((h, w, len(space_bands)), dtype=torch.float, device=device)
118
+ sp_m = torch.ones((h, w, len(space_groups)), dtype=torch.float, device=device)
119
+ t_x = torch.zeros((t, len(time_bands)), dtype=torch.float, device=device)
120
+ t_m = torch.ones((t, len(time_groups)), dtype=torch.float, device=device)
121
+ st_x = torch.zeros((len(static_bands)), dtype=torch.float, device=device)
122
+ st_m = torch.ones((len(static_groups)), dtype=torch.float, device=device)
123
 
124
+ for x, bands_list, group_key in zip([s1, s2], [bands["s1_bands"], bands["s2_bands"]], ["S1", "S2"]):
125
  if x is not None:
126
+ indices = [idx for idx, val in enumerate(space_time_bands) if val in bands_list]
127
+ groups_idx = [idx for idx, key in enumerate(space_time_groups) if group_key in key]
128
  s_t_x[:, :, :, indices] = x
129
  s_t_m[:, :, :, groups_idx] = 0
130
 
131
  for x, bands_list, group_key in zip(
132
+ [srtm, dw, wc], [bands["srtm_bands"], bands["dw_bands"], bands["wc_bands"]], ["SRTM", "DW", "WC"]
133
  ):
134
  if x is not None:
135
+ indices = [idx for idx, val in enumerate(space_bands) if val in bands_list]
136
+ groups_idx = [idx for idx, key in enumerate(space_groups) if group_key in key]
137
  sp_x[:, :, indices] = x
138
  sp_m[:, :, groups_idx] = 0
139
 
140
  for x, bands_list, group_key in zip(
141
+ [era5, tc, viirs], [bands["era5_bands"], bands["tc_bands"], bands["viirs_bands"]], ["ERA5", "TC", "VIIRS"]
142
  ):
143
  if x is not None:
144
+ indices = [idx for idx, val in enumerate(time_bands) if val in bands_list]
145
+ groups_idx = [idx for idx, key in enumerate(time_groups) if group_key in key]
146
  t_x[:, indices] = x
147
  t_m[:, groups_idx] = 0
148
 
149
  for x, bands_list, group_key in zip(
150
+ [landscan, latlon], [bands["landscan_bands"], bands["location_bands"]], ["LS", "location"]
151
  ):
152
  if x is not None:
153
  if group_key == "location":
154
  x = torch.as_tensor(to_cartesian(float(x[0]), float(x[1])), device=device)
155
+ indices = [idx for idx, val in enumerate(static_bands) if val in bands_list]
156
+ groups_idx = [idx for idx, key in enumerate(static_groups) if group_key in key]
157
  st_x[indices] = x
158
  st_m[groups_idx] = 0
159
 
160
  if months is None:
161
+ months = torch.ones((t), dtype=torch.long, device=device) * band_config.default_month
162
 
163
  if normalize:
164
+ normalizer = PretrainingNormalizer(band_config.pretraining_normalizing_dict)
165
  s_t_x = torch.from_numpy(normalizer(s_t_x.cpu().numpy())).to(device)
166
  sp_x = torch.from_numpy(normalizer(sp_x.cpu().numpy())).to(device)
167
  t_x = torch.from_numpy(normalizer(t_x.cpu().numpy())).to(device)
 
194
  "months",
195
  ]
196
 
197
+ def __init__(
198
+ self,
199
+ normalize: bool = True,
200
+ default_month: int = 6,
201
+ patch_size: int = 8,
202
+ s1_bands: Optional[list[str]] = None,
203
+ s2_bands: Optional[list[str]] = None,
204
+ era5_bands: Optional[list[str]] = None,
205
+ tc_bands: Optional[list[str]] = None,
206
+ viirs_bands: Optional[list[str]] = None,
207
+ srtm_bands: Optional[list[str]] = None,
208
+ dw_bands: Optional[list[str]] = None,
209
+ wc_bands: Optional[list[str]] = None,
210
+ landscan_bands: Optional[list[str]] = None,
211
+ location_bands: Optional[list[str]] = None,
212
+ space_time_band_groups: Optional[dict[str, list[str]]] = None,
213
+ time_band_groups: Optional[dict[str, list[str]]] = None,
214
+ space_band_groups: Optional[dict[str, list[str]]] = None,
215
+ pretraining_normalizing_dict: Optional[dict[str, dict[str, list[float]]]] = None,
216
+ **kwargs,
217
+ ):
218
  super().__init__(**kwargs)
219
  self.normalize = normalize
220
  self.default_month = default_month
221
  self.patch_size = patch_size
222
+ self.band_config = GalileoConfig(
223
+ default_month=default_month,
224
+ s1_bands=s1_bands,
225
+ s2_bands=s2_bands,
226
+ era5_bands=era5_bands,
227
+ tc_bands=tc_bands,
228
+ viirs_bands=viirs_bands,
229
+ srtm_bands=srtm_bands,
230
+ dw_bands=dw_bands,
231
+ wc_bands=wc_bands,
232
+ landscan_bands=landscan_bands,
233
+ location_bands=location_bands,
234
+ space_time_band_groups=space_time_band_groups,
235
+ time_band_groups=time_band_groups,
236
+ space_band_groups=space_band_groups,
237
+ pretraining_normalizing_dict=pretraining_normalizing_dict,
238
+ )
239
 
240
  def __call__(
241
  self,
 
282
  latlon=_to_tensor(latlon),
283
  months=months,
284
  normalize=normalize,
285
+ band_config=self.band_config,
286
  )
287
 
288
  if masked_output.space_time_x.dim() == 4:
galileo-nano-patch8/config.json CHANGED
@@ -43,5 +43,262 @@
43
  "AutoModel"
44
  ]
45
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
- }
 
43
  "AutoModel"
44
  ]
45
  }
46
+ },
47
+ "s1_bands": [
48
+ "VV",
49
+ "VH"
50
+ ],
51
+ "s2_bands": [
52
+ "B2",
53
+ "B3",
54
+ "B4",
55
+ "B5",
56
+ "B6",
57
+ "B7",
58
+ "B8",
59
+ "B8A",
60
+ "B11",
61
+ "B12"
62
+ ],
63
+ "era5_bands": [
64
+ "temperature_2m",
65
+ "total_precipitation_sum"
66
+ ],
67
+ "tc_bands": [
68
+ "def",
69
+ "soil",
70
+ "aet"
71
+ ],
72
+ "viirs_bands": [
73
+ "avg_rad"
74
+ ],
75
+ "srtm_bands": [
76
+ "elevation",
77
+ "slope"
78
+ ],
79
+ "dw_bands": [
80
+ "DW_water",
81
+ "DW_trees",
82
+ "DW_grass",
83
+ "DW_flooded_vegetation",
84
+ "DW_crops",
85
+ "DW_shrub_and_scrub",
86
+ "DW_built",
87
+ "DW_bare",
88
+ "DW_snow_and_ice"
89
+ ],
90
+ "wc_bands": [
91
+ "WC_temporarycrops",
92
+ "WC_maize",
93
+ "WC_wintercereals",
94
+ "WC_springcereals",
95
+ "WC_irrigation"
96
+ ],
97
+ "landscan_bands": [
98
+ "b1"
99
+ ],
100
+ "location_bands": [
101
+ "x",
102
+ "y",
103
+ "z"
104
+ ],
105
+ "space_time_band_groups": {
106
+ "S1": [
107
+ "VV",
108
+ "VH"
109
+ ],
110
+ "S2_RGB": [
111
+ "B2",
112
+ "B3",
113
+ "B4"
114
+ ],
115
+ "S2_Red_Edge": [
116
+ "B5",
117
+ "B6",
118
+ "B7"
119
+ ],
120
+ "S2_NIR_10m": [
121
+ "B8"
122
+ ],
123
+ "S2_NIR_20m": [
124
+ "B8A"
125
+ ],
126
+ "S2_SWIR": [
127
+ "B11",
128
+ "B12"
129
+ ],
130
+ "NDVI": [
131
+ "NDVI"
132
+ ]
133
+ },
134
+ "time_band_groups": {
135
+ "ERA5": [
136
+ "temperature_2m",
137
+ "total_precipitation_sum"
138
+ ],
139
+ "TC": [
140
+ "def",
141
+ "soil",
142
+ "aet"
143
+ ],
144
+ "VIIRS": [
145
+ "avg_rad"
146
+ ]
147
+ },
148
+ "space_band_groups": {
149
+ "SRTM": [
150
+ "elevation",
151
+ "slope"
152
+ ],
153
+ "DW": [
154
+ "DW_water",
155
+ "DW_trees",
156
+ "DW_grass",
157
+ "DW_flooded_vegetation",
158
+ "DW_crops",
159
+ "DW_shrub_and_scrub",
160
+ "DW_built",
161
+ "DW_bare",
162
+ "DW_snow_and_ice"
163
+ ],
164
+ "WC": [
165
+ "WC_temporarycrops",
166
+ "WC_maize",
167
+ "WC_wintercereals",
168
+ "WC_springcereals",
169
+ "WC_irrigation"
170
+ ]
171
+ },
172
+ "pretraining_normalizing_dict": {
173
+ "13": {
174
+ "mean": [
175
+ -11.728724389184965,
176
+ -18.85558188024017,
177
+ 1395.3408730676722,
178
+ 1338.4026921784578,
179
+ 1343.09883810357,
180
+ 1543.8607982512297,
181
+ 2186.2022069512263,
182
+ 2525.0932853316694,
183
+ 2410.3377187373408,
184
+ 2750.2854646886753,
185
+ 2234.911100061487,
186
+ 1474.5311266077113,
187
+ 0.2892116502999044
188
+ ],
189
+ "std": [
190
+ 4.887145774840316,
191
+ 5.730270320384293,
192
+ 917.7041440370853,
193
+ 913.2988423581528,
194
+ 1092.678723527555,
195
+ 1047.2206083460424,
196
+ 1048.0101611156767,
197
+ 1143.6903026819996,
198
+ 1098.979177731649,
199
+ 1204.472755085893,
200
+ 1145.9774063078878,
201
+ 980.2429840007796,
202
+ 0.2720939024500081
203
+ ]
204
+ },
205
+ "16": {
206
+ "mean": [
207
+ 673.0152819503361,
208
+ 5.930092668915115,
209
+ 0.10470439140978786,
210
+ 0.23965913270066183,
211
+ 0.08158044385860364,
212
+ 0.04246976254259546,
213
+ 0.11304392863520317,
214
+ 0.17329647890362473,
215
+ 0.0698981691616277,
216
+ 0.12130267132802142,
217
+ 0.04671318615236216,
218
+ 10.973119802517362,
219
+ 1.0927069179958768,
220
+ 1.6991394232855903,
221
+ 0.03720594618055555,
222
+ 1.3671352688259548
223
+ ],
224
+ "std": [
225
+ 983.0697298296237,
226
+ 8.167406789813247,
227
+ 0.18771647977504985,
228
+ 0.2368313455675914,
229
+ 0.08024268534756586,
230
+ 0.04045374496146404,
231
+ 0.11350342472061795,
232
+ 0.1279898111718168,
233
+ 0.12042341550438586,
234
+ 0.13602408145504347,
235
+ 0.043971116096060345,
236
+ 31.255340146970997,
237
+ 10.395974878206689,
238
+ 12.92380617159917,
239
+ 1.9285254295940466,
240
+ 11.612179775408928
241
+ ]
242
+ },
243
+ "6": {
244
+ "mean": [
245
+ 271.5674963541667,
246
+ 0.08554303677156568,
247
+ 657.3181260091111,
248
+ 692.1291795806885,
249
+ 562.781331880633,
250
+ 1.5647115934036673
251
+ ],
252
+ "std": [
253
+ 79.80828940314429,
254
+ 0.11669547098151486,
255
+ 704.0008695557707,
256
+ 925.0116126406431,
257
+ 453.2434022278578,
258
+ 7.513020170832818
259
+ ]
260
+ },
261
+ "18": {
262
+ "mean": [
263
+ 188.20315880851746,
264
+ 0.2804946561574936,
265
+ 0.11371652073860168,
266
+ 0.058778801321983334,
267
+ 0.10474256777763366,
268
+ 0.2396918488264084,
269
+ 0.08152248692512512,
270
+ 0.04248040814399719,
271
+ 0.11303179881572724,
272
+ 0.17326324067115784,
273
+ 0.06998309404850006,
274
+ 0.12122812910079957,
275
+ 0.04671641788482666,
276
+ 10.98456594619751,
277
+ 1.0968475807189941,
278
+ 1.6947754135131836,
279
+ 0.03320046615600586,
280
+ 1.3602827312469483
281
+ ],
282
+ "std": [
283
+ 1154.5919128300602,
284
+ 0.5276998078079327,
285
+ 0.7021637331734328,
286
+ 0.36528892213195063,
287
+ 0.17470213191865785,
288
+ 0.20411195416718833,
289
+ 0.0660782470089761,
290
+ 0.03380702424871257,
291
+ 0.09809195568521663,
292
+ 0.11292471052124119,
293
+ 0.09720748930233268,
294
+ 0.12912217763726777,
295
+ 0.0399973913151906,
296
+ 23.725471823867462,
297
+ 5.715238079725388,
298
+ 9.030481416228302,
299
+ 0.9950220242487364,
300
+ 7.754429123862099
301
+ ]
302
+ }
303
  }
304
+ }
galileo-nano-patch8/modeling_galileo.py CHANGED
@@ -26,95 +26,11 @@ from einops import rearrange, repeat
26
  from torch import Tensor, vmap
27
  from torch.jit import Final
28
 
29
- # constants
30
- CONFIG_FILENAME = "config.json"
31
- ENCODER_FILENAME = "encoder.pt"
32
- BASE_GSD = 10
33
-
34
- # band information
35
- S1_BANDS = ["VV", "VH"]
36
- S2_BANDS = [
37
- "B2",
38
- "B3",
39
- "B4",
40
- "B5",
41
- "B6",
42
- "B7",
43
- "B8",
44
- "B8A",
45
- "B11",
46
- "B12",
47
- ]
48
- ERA5_BANDS = ["temperature_2m", "total_precipitation_sum"]
49
- TC_BANDS = ["def", "soil", "aet"]
50
- VIIRS_BANDS = ["avg_rad"]
51
- SRTM_BANDS = ["elevation", "slope"]
52
- DW_BANDS = [
53
- "DW_water",
54
- "DW_trees",
55
- "DW_grass",
56
- "DW_flooded_vegetation",
57
- "DW_crops",
58
- "DW_shrub_and_scrub",
59
- "DW_built",
60
- "DW_bare",
61
- "DW_snow_and_ice",
62
- ]
63
- WC_BANDS = [
64
- "WC_temporarycrops",
65
- "WC_maize",
66
- "WC_wintercereals",
67
- "WC_springcereals",
68
- "WC_irrigation",
69
- ]
70
- STATIC_DW_BANDS = [f"{x}_static" for x in DW_BANDS]
71
- STATIC_WC_BANDS = [f"{x}_static" for x in WC_BANDS]
72
-
73
- LANDSCAN_BANDS = ["b1"]
74
- LOCATION_BANDS = ["x", "y", "z"]
75
-
76
- SPACE_TIME_BANDS = S1_BANDS + S2_BANDS + ["NDVI"]
77
- TIME_BANDS = ERA5_BANDS + TC_BANDS + VIIRS_BANDS
78
- SPACE_BANDS = SRTM_BANDS + DW_BANDS + WC_BANDS
79
- STATIC_BANDS = LANDSCAN_BANDS + LOCATION_BANDS + STATIC_DW_BANDS + STATIC_WC_BANDS
80
-
81
-
82
- SPACE_TIME_BANDS_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
83
- {
84
- "S1": [SPACE_TIME_BANDS.index(b) for b in S1_BANDS],
85
- "S2_RGB": [SPACE_TIME_BANDS.index(b) for b in ["B2", "B3", "B4"]],
86
- "S2_Red_Edge": [SPACE_TIME_BANDS.index(b) for b in ["B5", "B6", "B7"]],
87
- "S2_NIR_10m": [SPACE_TIME_BANDS.index(b) for b in ["B8"]],
88
- "S2_NIR_20m": [SPACE_TIME_BANDS.index(b) for b in ["B8A"]],
89
- "S2_SWIR": [SPACE_TIME_BANDS.index(b) for b in ["B11", "B12"]],
90
- "NDVI": [SPACE_TIME_BANDS.index("NDVI")],
91
- }
92
- )
93
-
94
- TIME_BAND_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
95
- {
96
- "ERA5": [TIME_BANDS.index(b) for b in ERA5_BANDS],
97
- "TC": [TIME_BANDS.index(b) for b in TC_BANDS],
98
- "VIIRS": [TIME_BANDS.index(b) for b in VIIRS_BANDS],
99
- }
100
- )
101
 
102
- SPACE_BAND_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
103
- {
104
- "SRTM": [SPACE_BANDS.index(b) for b in SRTM_BANDS],
105
- "DW": [SPACE_BANDS.index(b) for b in DW_BANDS],
106
- "WC": [SPACE_BANDS.index(b) for b in WC_BANDS],
107
- }
108
- )
109
-
110
- STATIC_BAND_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
111
- {
112
- "LS": [STATIC_BANDS.index(b) for b in LANDSCAN_BANDS],
113
- "location": [STATIC_BANDS.index(b) for b in LOCATION_BANDS],
114
- "DW_static": [STATIC_BANDS.index(b) for b in STATIC_DW_BANDS],
115
- "WC_static": [STATIC_BANDS.index(b) for b in STATIC_WC_BANDS],
116
- }
117
- )
118
 
119
 
120
  def get_2d_sincos_pos_embed_with_resolution(
@@ -565,13 +481,16 @@ class GalileoBase(nn.Module):
565
  base_patch_size: int = 4,
566
  use_channel_embs: bool = True,
567
  drop_path: float = 0.0,
 
568
  ):
569
  super().__init__()
570
 
571
- self.space_time_groups = SPACE_TIME_BANDS_GROUPS_IDX
572
- self.space_groups = SPACE_BAND_GROUPS_IDX
573
- self.time_groups = TIME_BAND_GROUPS_IDX
574
- self.static_groups = STATIC_BAND_GROUPS_IDX
 
 
575
  self.embedding_size = embedding_size
576
  self.base_patch_size = base_patch_size
577
 
@@ -606,16 +525,16 @@ class GalileoBase(nn.Module):
606
  else:
607
  args = {"requires_grad": False}
608
  self.s_t_channel_embed = nn.Parameter(
609
- torch.zeros(len(SPACE_TIME_BANDS_GROUPS_IDX), int(embedding_size * 0.25)), **args
610
  )
611
  self.sp_channel_embed = nn.Parameter(
612
- torch.zeros(len(SPACE_BAND_GROUPS_IDX), int(embedding_size * 0.25)), **args
613
  )
614
  self.t_channel_embed = nn.Parameter(
615
- torch.zeros(len(TIME_BAND_GROUPS_IDX), int(embedding_size * 0.25)), **args
616
  )
617
  self.st_channel_embed = nn.Parameter(
618
- torch.zeros(len(STATIC_BAND_GROUPS_IDX), int(embedding_size * 0.25)), **args
619
  )
620
 
621
  self.apply(self._init_weights)
@@ -720,7 +639,7 @@ class GalileoBase(nn.Module):
720
  if patch_size is None:
721
  patch_size = self.base_patch_size
722
  token_res = input_res * patch_size
723
- gsd_ratio = token_res / BASE_GSD
724
 
725
  assert h == w, "get_2d_sincos_pos_embed_with_resolution currently requires that h==w"
726
  spatial_embed = get_2d_sincos_pos_embed_with_resolution(
@@ -755,6 +674,7 @@ class Encoder(GalileoBase):
755
  max_sequence_length=24,
756
  freeze_projections: bool = False,
757
  drop_path: float = 0.0,
 
758
  ):
759
  super().__init__(
760
  embedding_size,
@@ -765,6 +685,7 @@ class Encoder(GalileoBase):
765
  max_patch_size,
766
  use_channel_embs=True,
767
  drop_path=drop_path,
 
768
  )
769
 
770
  self.space_time_embed = nn.ModuleDict(
@@ -1108,11 +1029,14 @@ class Encoder(GalileoBase):
1108
  st_m: torch.Tensor,
1109
  months: torch.Tensor,
1110
  patch_size: int,
1111
- input_resolution_m: Optional[int] = BASE_GSD,
1112
  exit_after: Optional[int] = None,
1113
  token_exit_cfg: Optional[Dict] = None,
1114
  add_layernorm_on_exit: bool = True,
1115
  ):
 
 
 
1116
  (
1117
  s_t_x,
1118
  sp_x,
@@ -1161,25 +1085,31 @@ class Encoder(GalileoBase):
1161
  )
1162
 
1163
  @classmethod
1164
- def load_from_folder(cls, folder: Path, device: torch.device):
1165
- if not (folder / CONFIG_FILENAME).exists():
 
 
 
 
 
 
1166
  all_files_in_folder = [f.name for f in folder.glob("*")]
1167
  raise ValueError(
1168
- f"Expected {CONFIG_FILENAME} in {folder}, found {all_files_in_folder}"
1169
  )
1170
- if not (folder / ENCODER_FILENAME).exists():
1171
  all_files_in_folder = [f.name for f in folder.glob("*")]
1172
  raise ValueError(
1173
- f"Expected {ENCODER_FILENAME} in {folder}, found {all_files_in_folder}"
1174
  )
1175
 
1176
- with (folder / CONFIG_FILENAME).open("r") as f:
1177
  config = json.load(f)
1178
  model_config = config["model"]
1179
  encoder_config = model_config["encoder"]
1180
  encoder = cls(**encoder_config)
1181
 
1182
- state_dict = torch.load(folder / ENCODER_FILENAME, map_location=device)
1183
  for key in list(state_dict.keys()):
1184
  # this cleans the state dict, which occasionally had an extra
1185
  # ".backbone" included in the key names
@@ -1189,6 +1119,141 @@ class Encoder(GalileoBase):
1189
  logger = logging.get_logger(__name__)
1190
 
1191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1192
  class GalileoConfig(PreTrainedConfig):
1193
  model_type = "galileo"
1194
 
@@ -1206,6 +1271,20 @@ class GalileoConfig(PreTrainedConfig):
1206
  default_month: int = 6,
1207
  global_pool: bool = True,
1208
  input_resolution_m: int = 10,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1209
  **kwargs,
1210
  ):
1211
  super().__init__(**kwargs)
@@ -1221,6 +1300,89 @@ class GalileoConfig(PreTrainedConfig):
1221
  self.default_month = default_month
1222
  self.global_pool = global_pool
1223
  self.input_resolution_m = input_resolution_m
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1224
 
1225
 
1226
  class GalileoPreTrainedModel(PreTrainedModel):
@@ -1245,6 +1407,7 @@ class GalileoEncoderModel(GalileoPreTrainedModel):
1245
  max_sequence_length=config.max_sequence_length,
1246
  freeze_projections=config.freeze_projections,
1247
  drop_path=config.drop_path,
 
1248
  )
1249
  self.add_pooling_layer = add_pooling_layer and config.global_pool
1250
  self.post_init()
 
26
  from torch import Tensor, vmap
27
  from torch.jit import Final
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ def _band_group_indices(
31
+ bands: Sequence[str], groups: Dict[str, List[str]]
32
+ ) -> OrderedDictType[str, List[int]]:
33
+ return OrderedDict((name, [bands.index(b) for b in group_bands]) for name, group_bands in groups.items())
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
 
36
  def get_2d_sincos_pos_embed_with_resolution(
 
481
  base_patch_size: int = 4,
482
  use_channel_embs: bool = True,
483
  drop_path: float = 0.0,
484
+ band_layout: Optional[Dict[str, Any]] = None,
485
  ):
486
  super().__init__()
487
 
488
+ band_layout = band_layout or GalileoConfig().band_layout()
489
+ self.space_time_groups = band_layout["space_time_groups"]
490
+ self.space_groups = band_layout["space_groups"]
491
+ self.time_groups = band_layout["time_groups"]
492
+ self.static_groups = band_layout["static_groups"]
493
+ self.base_gsd = band_layout["input_resolution_m"]
494
  self.embedding_size = embedding_size
495
  self.base_patch_size = base_patch_size
496
 
 
525
  else:
526
  args = {"requires_grad": False}
527
  self.s_t_channel_embed = nn.Parameter(
528
+ torch.zeros(len(self.space_time_groups), int(embedding_size * 0.25)), **args
529
  )
530
  self.sp_channel_embed = nn.Parameter(
531
+ torch.zeros(len(self.space_groups), int(embedding_size * 0.25)), **args
532
  )
533
  self.t_channel_embed = nn.Parameter(
534
+ torch.zeros(len(self.time_groups), int(embedding_size * 0.25)), **args
535
  )
536
  self.st_channel_embed = nn.Parameter(
537
+ torch.zeros(len(self.static_groups), int(embedding_size * 0.25)), **args
538
  )
539
 
540
  self.apply(self._init_weights)
 
639
  if patch_size is None:
640
  patch_size = self.base_patch_size
641
  token_res = input_res * patch_size
642
+ gsd_ratio = token_res / self.base_gsd
643
 
644
  assert h == w, "get_2d_sincos_pos_embed_with_resolution currently requires that h==w"
645
  spatial_embed = get_2d_sincos_pos_embed_with_resolution(
 
674
  max_sequence_length=24,
675
  freeze_projections: bool = False,
676
  drop_path: float = 0.0,
677
+ band_layout: Optional[Dict[str, Any]] = None,
678
  ):
679
  super().__init__(
680
  embedding_size,
 
685
  max_patch_size,
686
  use_channel_embs=True,
687
  drop_path=drop_path,
688
+ band_layout=band_layout,
689
  )
690
 
691
  self.space_time_embed = nn.ModuleDict(
 
1029
  st_m: torch.Tensor,
1030
  months: torch.Tensor,
1031
  patch_size: int,
1032
+ input_resolution_m: Optional[int] = None,
1033
  exit_after: Optional[int] = None,
1034
  token_exit_cfg: Optional[Dict] = None,
1035
  add_layernorm_on_exit: bool = True,
1036
  ):
1037
+ if input_resolution_m is None:
1038
+ input_resolution_m = self.base_gsd
1039
+
1040
  (
1041
  s_t_x,
1042
  sp_x,
 
1085
  )
1086
 
1087
  @classmethod
1088
+ def load_from_folder(
1089
+ cls,
1090
+ folder: Path,
1091
+ device: torch.device,
1092
+ config_filename: str = "config.json",
1093
+ encoder_filename: str = "encoder.pt",
1094
+ ):
1095
+ if not (folder / config_filename).exists():
1096
  all_files_in_folder = [f.name for f in folder.glob("*")]
1097
  raise ValueError(
1098
+ f"Expected {config_filename} in {folder}, found {all_files_in_folder}"
1099
  )
1100
+ if not (folder / encoder_filename).exists():
1101
  all_files_in_folder = [f.name for f in folder.glob("*")]
1102
  raise ValueError(
1103
+ f"Expected {encoder_filename} in {folder}, found {all_files_in_folder}"
1104
  )
1105
 
1106
+ with (folder / config_filename).open("r") as f:
1107
  config = json.load(f)
1108
  model_config = config["model"]
1109
  encoder_config = model_config["encoder"]
1110
  encoder = cls(**encoder_config)
1111
 
1112
+ state_dict = torch.load(folder / encoder_filename, map_location=device)
1113
  for key in list(state_dict.keys()):
1114
  # this cleans the state dict, which occasionally had an extra
1115
  # ".backbone" included in the key names
 
1119
  logger = logging.get_logger(__name__)
1120
 
1121
 
1122
+ def _default_pretraining_normalizing_dict() -> Dict[str, Dict[str, List[float]]]:
1123
+ return {
1124
+ "13": {
1125
+ "mean": [
1126
+ -11.728724389184965,
1127
+ -18.85558188024017,
1128
+ 1395.3408730676722,
1129
+ 1338.4026921784578,
1130
+ 1343.09883810357,
1131
+ 1543.8607982512297,
1132
+ 2186.2022069512263,
1133
+ 2525.0932853316694,
1134
+ 2410.3377187373408,
1135
+ 2750.2854646886753,
1136
+ 2234.911100061487,
1137
+ 1474.5311266077113,
1138
+ 0.2892116502999044,
1139
+ ],
1140
+ "std": [
1141
+ 4.887145774840316,
1142
+ 5.730270320384293,
1143
+ 917.7041440370853,
1144
+ 913.2988423581528,
1145
+ 1092.678723527555,
1146
+ 1047.2206083460424,
1147
+ 1048.0101611156767,
1148
+ 1143.6903026819996,
1149
+ 1098.979177731649,
1150
+ 1204.472755085893,
1151
+ 1145.9774063078878,
1152
+ 980.2429840007796,
1153
+ 0.2720939024500081,
1154
+ ],
1155
+ },
1156
+ "16": {
1157
+ "mean": [
1158
+ 673.0152819503361,
1159
+ 5.930092668915115,
1160
+ 0.10470439140978786,
1161
+ 0.23965913270066183,
1162
+ 0.08158044385860364,
1163
+ 0.04246976254259546,
1164
+ 0.11304392863520317,
1165
+ 0.17329647890362473,
1166
+ 0.0698981691616277,
1167
+ 0.12130267132802142,
1168
+ 0.04671318615236216,
1169
+ 10.973119802517362,
1170
+ 1.0927069179958768,
1171
+ 1.6991394232855903,
1172
+ 0.03720594618055555,
1173
+ 1.3671352688259548,
1174
+ ],
1175
+ "std": [
1176
+ 983.0697298296237,
1177
+ 8.167406789813247,
1178
+ 0.18771647977504985,
1179
+ 0.2368313455675914,
1180
+ 0.08024268534756586,
1181
+ 0.04045374496146404,
1182
+ 0.11350342472061795,
1183
+ 0.1279898111718168,
1184
+ 0.12042341550438586,
1185
+ 0.13602408145504347,
1186
+ 0.043971116096060345,
1187
+ 31.255340146970997,
1188
+ 10.395974878206689,
1189
+ 12.92380617159917,
1190
+ 1.9285254295940466,
1191
+ 11.612179775408928,
1192
+ ],
1193
+ },
1194
+ "6": {
1195
+ "mean": [
1196
+ 271.5674963541667,
1197
+ 0.08554303677156568,
1198
+ 657.3181260091111,
1199
+ 692.1291795806885,
1200
+ 562.781331880633,
1201
+ 1.5647115934036673,
1202
+ ],
1203
+ "std": [
1204
+ 79.80828940314429,
1205
+ 0.11669547098151486,
1206
+ 704.0008695557707,
1207
+ 925.0116126406431,
1208
+ 453.2434022278578,
1209
+ 7.513020170832818,
1210
+ ],
1211
+ },
1212
+ "18": {
1213
+ "mean": [
1214
+ 188.20315880851746,
1215
+ 0.2804946561574936,
1216
+ 0.11371652073860168,
1217
+ 0.058778801321983334,
1218
+ 0.10474256777763366,
1219
+ 0.2396918488264084,
1220
+ 0.08152248692512512,
1221
+ 0.04248040814399719,
1222
+ 0.11303179881572724,
1223
+ 0.17326324067115784,
1224
+ 0.06998309404850006,
1225
+ 0.12122812910079957,
1226
+ 0.04671641788482666,
1227
+ 10.98456594619751,
1228
+ 1.0968475807189941,
1229
+ 1.6947754135131836,
1230
+ 0.03320046615600586,
1231
+ 1.3602827312469483,
1232
+ ],
1233
+ "std": [
1234
+ 1154.5919128300602,
1235
+ 0.5276998078079327,
1236
+ 0.7021637331734328,
1237
+ 0.36528892213195063,
1238
+ 0.17470213191865785,
1239
+ 0.20411195416718833,
1240
+ 0.0660782470089761,
1241
+ 0.03380702424871257,
1242
+ 0.09809195568521663,
1243
+ 0.11292471052124119,
1244
+ 0.09720748930233268,
1245
+ 0.12912217763726777,
1246
+ 0.0399973913151906,
1247
+ 23.725471823867462,
1248
+ 5.715238079725388,
1249
+ 9.030481416228302,
1250
+ 0.9950220242487364,
1251
+ 7.754429123862099,
1252
+ ],
1253
+ },
1254
+ }
1255
+
1256
+
1257
  class GalileoConfig(PreTrainedConfig):
1258
  model_type = "galileo"
1259
 
 
1271
  default_month: int = 6,
1272
  global_pool: bool = True,
1273
  input_resolution_m: int = 10,
1274
+ s1_bands: Optional[List[str]] = None,
1275
+ s2_bands: Optional[List[str]] = None,
1276
+ era5_bands: Optional[List[str]] = None,
1277
+ tc_bands: Optional[List[str]] = None,
1278
+ viirs_bands: Optional[List[str]] = None,
1279
+ srtm_bands: Optional[List[str]] = None,
1280
+ dw_bands: Optional[List[str]] = None,
1281
+ wc_bands: Optional[List[str]] = None,
1282
+ landscan_bands: Optional[List[str]] = None,
1283
+ location_bands: Optional[List[str]] = None,
1284
+ space_time_band_groups: Optional[Dict[str, List[str]]] = None,
1285
+ time_band_groups: Optional[Dict[str, List[str]]] = None,
1286
+ space_band_groups: Optional[Dict[str, List[str]]] = None,
1287
+ pretraining_normalizing_dict: Optional[Dict[str, Dict[str, List[float]]]] = None,
1288
  **kwargs,
1289
  ):
1290
  super().__init__(**kwargs)
 
1300
  self.default_month = default_month
1301
  self.global_pool = global_pool
1302
  self.input_resolution_m = input_resolution_m
1303
+ self.s1_bands = s1_bands if s1_bands is not None else ["VV", "VH"]
1304
+ self.s2_bands = s2_bands if s2_bands is not None else [
1305
+ "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B8A", "B11", "B12",
1306
+ ]
1307
+ self.era5_bands = era5_bands if era5_bands is not None else [
1308
+ "temperature_2m", "total_precipitation_sum",
1309
+ ]
1310
+ self.tc_bands = tc_bands if tc_bands is not None else ["def", "soil", "aet"]
1311
+ self.viirs_bands = viirs_bands if viirs_bands is not None else ["avg_rad"]
1312
+ self.srtm_bands = srtm_bands if srtm_bands is not None else ["elevation", "slope"]
1313
+ self.dw_bands = dw_bands if dw_bands is not None else [
1314
+ "DW_water", "DW_trees", "DW_grass", "DW_flooded_vegetation", "DW_crops",
1315
+ "DW_shrub_and_scrub", "DW_built", "DW_bare", "DW_snow_and_ice",
1316
+ ]
1317
+ self.wc_bands = wc_bands if wc_bands is not None else [
1318
+ "WC_temporarycrops", "WC_maize", "WC_wintercereals", "WC_springcereals", "WC_irrigation",
1319
+ ]
1320
+ self.landscan_bands = landscan_bands if landscan_bands is not None else ["b1"]
1321
+ self.location_bands = location_bands if location_bands is not None else ["x", "y", "z"]
1322
+ self.space_time_band_groups = space_time_band_groups if space_time_band_groups is not None else {
1323
+ "S1": ["VV", "VH"],
1324
+ "S2_RGB": ["B2", "B3", "B4"],
1325
+ "S2_Red_Edge": ["B5", "B6", "B7"],
1326
+ "S2_NIR_10m": ["B8"],
1327
+ "S2_NIR_20m": ["B8A"],
1328
+ "S2_SWIR": ["B11", "B12"],
1329
+ "NDVI": ["NDVI"],
1330
+ }
1331
+ self.time_band_groups = time_band_groups if time_band_groups is not None else {
1332
+ "ERA5": ["temperature_2m", "total_precipitation_sum"],
1333
+ "TC": ["def", "soil", "aet"],
1334
+ "VIIRS": ["avg_rad"],
1335
+ }
1336
+ self.space_band_groups = space_band_groups if space_band_groups is not None else {
1337
+ "SRTM": ["elevation", "slope"],
1338
+ "DW": [
1339
+ "DW_water", "DW_trees", "DW_grass", "DW_flooded_vegetation", "DW_crops",
1340
+ "DW_shrub_and_scrub", "DW_built", "DW_bare", "DW_snow_and_ice",
1341
+ ],
1342
+ "WC": [
1343
+ "WC_temporarycrops", "WC_maize", "WC_wintercereals", "WC_springcereals", "WC_irrigation",
1344
+ ],
1345
+ }
1346
+ self.pretraining_normalizing_dict = (
1347
+ pretraining_normalizing_dict
1348
+ if pretraining_normalizing_dict is not None
1349
+ else _default_pretraining_normalizing_dict()
1350
+ )
1351
+
1352
+ def band_layout(self) -> Dict[str, Any]:
1353
+ space_time_bands = self.s1_bands + self.s2_bands + ["NDVI"]
1354
+ time_bands = self.era5_bands + self.tc_bands + self.viirs_bands
1355
+ space_bands = self.srtm_bands + self.dw_bands + self.wc_bands
1356
+ static_dw_bands = [f"{band}_static" for band in self.dw_bands]
1357
+ static_wc_bands = [f"{band}_static" for band in self.wc_bands]
1358
+ static_bands = self.landscan_bands + self.location_bands + static_dw_bands + static_wc_bands
1359
+ static_band_groups = {
1360
+ "LS": self.landscan_bands,
1361
+ "location": self.location_bands,
1362
+ "DW_static": static_dw_bands,
1363
+ "WC_static": static_wc_bands,
1364
+ }
1365
+ return {
1366
+ "s1_bands": self.s1_bands,
1367
+ "s2_bands": self.s2_bands,
1368
+ "era5_bands": self.era5_bands,
1369
+ "tc_bands": self.tc_bands,
1370
+ "viirs_bands": self.viirs_bands,
1371
+ "srtm_bands": self.srtm_bands,
1372
+ "dw_bands": self.dw_bands,
1373
+ "wc_bands": self.wc_bands,
1374
+ "landscan_bands": self.landscan_bands,
1375
+ "location_bands": self.location_bands,
1376
+ "space_time_bands": space_time_bands,
1377
+ "time_bands": time_bands,
1378
+ "space_bands": space_bands,
1379
+ "static_bands": static_bands,
1380
+ "space_time_groups": _band_group_indices(space_time_bands, self.space_time_band_groups),
1381
+ "time_groups": _band_group_indices(time_bands, self.time_band_groups),
1382
+ "space_groups": _band_group_indices(space_bands, self.space_band_groups),
1383
+ "static_groups": _band_group_indices(static_bands, static_band_groups),
1384
+ "input_resolution_m": self.input_resolution_m,
1385
+ }
1386
 
1387
 
1388
  class GalileoPreTrainedModel(PreTrainedModel):
 
1407
  max_sequence_length=config.max_sequence_length,
1408
  freeze_projections=config.freeze_projections,
1409
  drop_path=config.drop_path,
1410
+ band_layout=config.band_layout(),
1411
  )
1412
  self.add_pooling_layer = add_pooling_layer and config.global_pool
1413
  self.post_init()
galileo-nano-patch8/preprocessor_config.json CHANGED
@@ -5,5 +5,262 @@
5
  "patch_size": 8,
6
  "auto_map": {
7
  "AutoProcessor": "processing_galileo.GalileoProcessor"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  }
9
- }
 
5
  "patch_size": 8,
6
  "auto_map": {
7
  "AutoProcessor": "processing_galileo.GalileoProcessor"
8
+ },
9
+ "s1_bands": [
10
+ "VV",
11
+ "VH"
12
+ ],
13
+ "s2_bands": [
14
+ "B2",
15
+ "B3",
16
+ "B4",
17
+ "B5",
18
+ "B6",
19
+ "B7",
20
+ "B8",
21
+ "B8A",
22
+ "B11",
23
+ "B12"
24
+ ],
25
+ "era5_bands": [
26
+ "temperature_2m",
27
+ "total_precipitation_sum"
28
+ ],
29
+ "tc_bands": [
30
+ "def",
31
+ "soil",
32
+ "aet"
33
+ ],
34
+ "viirs_bands": [
35
+ "avg_rad"
36
+ ],
37
+ "srtm_bands": [
38
+ "elevation",
39
+ "slope"
40
+ ],
41
+ "dw_bands": [
42
+ "DW_water",
43
+ "DW_trees",
44
+ "DW_grass",
45
+ "DW_flooded_vegetation",
46
+ "DW_crops",
47
+ "DW_shrub_and_scrub",
48
+ "DW_built",
49
+ "DW_bare",
50
+ "DW_snow_and_ice"
51
+ ],
52
+ "wc_bands": [
53
+ "WC_temporarycrops",
54
+ "WC_maize",
55
+ "WC_wintercereals",
56
+ "WC_springcereals",
57
+ "WC_irrigation"
58
+ ],
59
+ "landscan_bands": [
60
+ "b1"
61
+ ],
62
+ "location_bands": [
63
+ "x",
64
+ "y",
65
+ "z"
66
+ ],
67
+ "space_time_band_groups": {
68
+ "S1": [
69
+ "VV",
70
+ "VH"
71
+ ],
72
+ "S2_RGB": [
73
+ "B2",
74
+ "B3",
75
+ "B4"
76
+ ],
77
+ "S2_Red_Edge": [
78
+ "B5",
79
+ "B6",
80
+ "B7"
81
+ ],
82
+ "S2_NIR_10m": [
83
+ "B8"
84
+ ],
85
+ "S2_NIR_20m": [
86
+ "B8A"
87
+ ],
88
+ "S2_SWIR": [
89
+ "B11",
90
+ "B12"
91
+ ],
92
+ "NDVI": [
93
+ "NDVI"
94
+ ]
95
+ },
96
+ "time_band_groups": {
97
+ "ERA5": [
98
+ "temperature_2m",
99
+ "total_precipitation_sum"
100
+ ],
101
+ "TC": [
102
+ "def",
103
+ "soil",
104
+ "aet"
105
+ ],
106
+ "VIIRS": [
107
+ "avg_rad"
108
+ ]
109
+ },
110
+ "space_band_groups": {
111
+ "SRTM": [
112
+ "elevation",
113
+ "slope"
114
+ ],
115
+ "DW": [
116
+ "DW_water",
117
+ "DW_trees",
118
+ "DW_grass",
119
+ "DW_flooded_vegetation",
120
+ "DW_crops",
121
+ "DW_shrub_and_scrub",
122
+ "DW_built",
123
+ "DW_bare",
124
+ "DW_snow_and_ice"
125
+ ],
126
+ "WC": [
127
+ "WC_temporarycrops",
128
+ "WC_maize",
129
+ "WC_wintercereals",
130
+ "WC_springcereals",
131
+ "WC_irrigation"
132
+ ]
133
+ },
134
+ "pretraining_normalizing_dict": {
135
+ "13": {
136
+ "mean": [
137
+ -11.728724389184965,
138
+ -18.85558188024017,
139
+ 1395.3408730676722,
140
+ 1338.4026921784578,
141
+ 1343.09883810357,
142
+ 1543.8607982512297,
143
+ 2186.2022069512263,
144
+ 2525.0932853316694,
145
+ 2410.3377187373408,
146
+ 2750.2854646886753,
147
+ 2234.911100061487,
148
+ 1474.5311266077113,
149
+ 0.2892116502999044
150
+ ],
151
+ "std": [
152
+ 4.887145774840316,
153
+ 5.730270320384293,
154
+ 917.7041440370853,
155
+ 913.2988423581528,
156
+ 1092.678723527555,
157
+ 1047.2206083460424,
158
+ 1048.0101611156767,
159
+ 1143.6903026819996,
160
+ 1098.979177731649,
161
+ 1204.472755085893,
162
+ 1145.9774063078878,
163
+ 980.2429840007796,
164
+ 0.2720939024500081
165
+ ]
166
+ },
167
+ "16": {
168
+ "mean": [
169
+ 673.0152819503361,
170
+ 5.930092668915115,
171
+ 0.10470439140978786,
172
+ 0.23965913270066183,
173
+ 0.08158044385860364,
174
+ 0.04246976254259546,
175
+ 0.11304392863520317,
176
+ 0.17329647890362473,
177
+ 0.0698981691616277,
178
+ 0.12130267132802142,
179
+ 0.04671318615236216,
180
+ 10.973119802517362,
181
+ 1.0927069179958768,
182
+ 1.6991394232855903,
183
+ 0.03720594618055555,
184
+ 1.3671352688259548
185
+ ],
186
+ "std": [
187
+ 983.0697298296237,
188
+ 8.167406789813247,
189
+ 0.18771647977504985,
190
+ 0.2368313455675914,
191
+ 0.08024268534756586,
192
+ 0.04045374496146404,
193
+ 0.11350342472061795,
194
+ 0.1279898111718168,
195
+ 0.12042341550438586,
196
+ 0.13602408145504347,
197
+ 0.043971116096060345,
198
+ 31.255340146970997,
199
+ 10.395974878206689,
200
+ 12.92380617159917,
201
+ 1.9285254295940466,
202
+ 11.612179775408928
203
+ ]
204
+ },
205
+ "6": {
206
+ "mean": [
207
+ 271.5674963541667,
208
+ 0.08554303677156568,
209
+ 657.3181260091111,
210
+ 692.1291795806885,
211
+ 562.781331880633,
212
+ 1.5647115934036673
213
+ ],
214
+ "std": [
215
+ 79.80828940314429,
216
+ 0.11669547098151486,
217
+ 704.0008695557707,
218
+ 925.0116126406431,
219
+ 453.2434022278578,
220
+ 7.513020170832818
221
+ ]
222
+ },
223
+ "18": {
224
+ "mean": [
225
+ 188.20315880851746,
226
+ 0.2804946561574936,
227
+ 0.11371652073860168,
228
+ 0.058778801321983334,
229
+ 0.10474256777763366,
230
+ 0.2396918488264084,
231
+ 0.08152248692512512,
232
+ 0.04248040814399719,
233
+ 0.11303179881572724,
234
+ 0.17326324067115784,
235
+ 0.06998309404850006,
236
+ 0.12122812910079957,
237
+ 0.04671641788482666,
238
+ 10.98456594619751,
239
+ 1.0968475807189941,
240
+ 1.6947754135131836,
241
+ 0.03320046615600586,
242
+ 1.3602827312469483
243
+ ],
244
+ "std": [
245
+ 1154.5919128300602,
246
+ 0.5276998078079327,
247
+ 0.7021637331734328,
248
+ 0.36528892213195063,
249
+ 0.17470213191865785,
250
+ 0.20411195416718833,
251
+ 0.0660782470089761,
252
+ 0.03380702424871257,
253
+ 0.09809195568521663,
254
+ 0.11292471052124119,
255
+ 0.09720748930233268,
256
+ 0.12912217763726777,
257
+ 0.0399973913151906,
258
+ 23.725471823867462,
259
+ 5.715238079725388,
260
+ 9.030481416228302,
261
+ 0.9950220242487364,
262
+ 7.754429123862099
263
+ ]
264
+ }
265
  }
266
+ }
galileo-nano-patch8/processing_galileo.py CHANGED
@@ -4,7 +4,6 @@
4
  from __future__ import annotations
5
 
6
  import math
7
- from collections import OrderedDict
8
  from typing import Any, NamedTuple, Optional, Union
9
 
10
  import numpy as np
@@ -14,191 +13,7 @@ from transformers.feature_extraction_utils import BatchFeature
14
  from transformers.processing_utils import ProcessorMixin
15
  from transformers.utils import TensorType
16
 
17
-
18
- S1_BANDS = ["VV", "VH"]
19
- S2_BANDS = ["B2", "B3", "B4", "B5", "B6", "B7", "B8", "B8A", "B11", "B12"]
20
- ERA5_BANDS = ["temperature_2m", "total_precipitation_sum"]
21
- TC_BANDS = ["def", "soil", "aet"]
22
- VIIRS_BANDS = ["avg_rad"]
23
- SRTM_BANDS = ["elevation", "slope"]
24
- DW_BANDS = [
25
- "DW_water", "DW_trees", "DW_grass", "DW_flooded_vegetation", "DW_crops",
26
- "DW_shrub_and_scrub", "DW_built", "DW_bare", "DW_snow_and_ice",
27
- ]
28
- WC_BANDS = [
29
- "WC_temporarycrops", "WC_maize", "WC_wintercereals", "WC_springcereals", "WC_irrigation",
30
- ]
31
- LANDSCAN_BANDS = ["b1"]
32
- LOCATION_BANDS = ["x", "y", "z"]
33
- STATIC_DW_BANDS = [f"{x}_static" for x in DW_BANDS]
34
- STATIC_WC_BANDS = [f"{x}_static" for x in WC_BANDS]
35
-
36
- SPACE_TIME_BANDS = S1_BANDS + S2_BANDS + ["NDVI"]
37
- TIME_BANDS = ERA5_BANDS + TC_BANDS + VIIRS_BANDS
38
- SPACE_BANDS = SRTM_BANDS + DW_BANDS + WC_BANDS
39
- STATIC_BANDS = LANDSCAN_BANDS + LOCATION_BANDS + STATIC_DW_BANDS + STATIC_WC_BANDS
40
-
41
- SPACE_TIME_BANDS_GROUPS_IDX = OrderedDict({
42
- "S1": [SPACE_TIME_BANDS.index(b) for b in S1_BANDS],
43
- "S2_RGB": [SPACE_TIME_BANDS.index(b) for b in ["B2", "B3", "B4"]],
44
- "S2_Red_Edge": [SPACE_TIME_BANDS.index(b) for b in ["B5", "B6", "B7"]],
45
- "S2_NIR_10m": [SPACE_TIME_BANDS.index(b) for b in ["B8"]],
46
- "S2_NIR_20m": [SPACE_TIME_BANDS.index(b) for b in ["B8A"]],
47
- "S2_SWIR": [SPACE_TIME_BANDS.index(b) for b in ["B11", "B12"]],
48
- "NDVI": [SPACE_TIME_BANDS.index("NDVI")],
49
- })
50
- TIME_BAND_GROUPS_IDX = OrderedDict({
51
- "ERA5": [TIME_BANDS.index(b) for b in ERA5_BANDS],
52
- "TC": [TIME_BANDS.index(b) for b in TC_BANDS],
53
- "VIIRS": [TIME_BANDS.index(b) for b in VIIRS_BANDS],
54
- })
55
- SPACE_BAND_GROUPS_IDX = OrderedDict({
56
- "SRTM": [SPACE_BANDS.index(b) for b in SRTM_BANDS],
57
- "DW": [SPACE_BANDS.index(b) for b in DW_BANDS],
58
- "WC": [SPACE_BANDS.index(b) for b in WC_BANDS],
59
- })
60
- STATIC_BAND_GROUPS_IDX = OrderedDict({
61
- "LS": [STATIC_BANDS.index(b) for b in LANDSCAN_BANDS],
62
- "location": [STATIC_BANDS.index(b) for b in LOCATION_BANDS],
63
- "DW_static": [STATIC_BANDS.index(b) for b in STATIC_DW_BANDS],
64
- "WC_static": [STATIC_BANDS.index(b) for b in STATIC_WC_BANDS],
65
- })
66
-
67
-
68
- DEFAULT_MONTH = 5
69
-
70
- PRETRAINING_NORMALIZING_DICT = {
71
- "13": {
72
- "mean": [
73
- -11.728724389184965,
74
- -18.85558188024017,
75
- 1395.3408730676722,
76
- 1338.4026921784578,
77
- 1343.09883810357,
78
- 1543.8607982512297,
79
- 2186.2022069512263,
80
- 2525.0932853316694,
81
- 2410.3377187373408,
82
- 2750.2854646886753,
83
- 2234.911100061487,
84
- 1474.5311266077113,
85
- 0.2892116502999044,
86
- ],
87
- "std": [
88
- 4.887145774840316,
89
- 5.730270320384293,
90
- 917.7041440370853,
91
- 913.2988423581528,
92
- 1092.678723527555,
93
- 1047.2206083460424,
94
- 1048.0101611156767,
95
- 1143.6903026819996,
96
- 1098.979177731649,
97
- 1204.472755085893,
98
- 1145.9774063078878,
99
- 980.2429840007796,
100
- 0.2720939024500081,
101
- ],
102
- },
103
- "16": {
104
- "mean": [
105
- 673.0152819503361,
106
- 5.930092668915115,
107
- 0.10470439140978786,
108
- 0.23965913270066183,
109
- 0.08158044385860364,
110
- 0.04246976254259546,
111
- 0.11304392863520317,
112
- 0.17329647890362473,
113
- 0.0698981691616277,
114
- 0.12130267132802142,
115
- 0.04671318615236216,
116
- 10.973119802517362,
117
- 1.0927069179958768,
118
- 1.6991394232855903,
119
- 0.03720594618055555,
120
- 1.3671352688259548,
121
- ],
122
- "std": [
123
- 983.0697298296237,
124
- 8.167406789813247,
125
- 0.18771647977504985,
126
- 0.2368313455675914,
127
- 0.08024268534756586,
128
- 0.04045374496146404,
129
- 0.11350342472061795,
130
- 0.1279898111718168,
131
- 0.12042341550438586,
132
- 0.13602408145504347,
133
- 0.043971116096060345,
134
- 31.255340146970997,
135
- 10.395974878206689,
136
- 12.92380617159917,
137
- 1.9285254295940466,
138
- 11.612179775408928,
139
- ],
140
- },
141
- "6": {
142
- "mean": [
143
- 271.5674963541667,
144
- 0.08554303677156568,
145
- 657.3181260091111,
146
- 692.1291795806885,
147
- 562.781331880633,
148
- 1.5647115934036673,
149
- ],
150
- "std": [
151
- 79.80828940314429,
152
- 0.11669547098151486,
153
- 704.0008695557707,
154
- 925.0116126406431,
155
- 453.2434022278578,
156
- 7.513020170832818,
157
- ],
158
- },
159
- "18": {
160
- "mean": [
161
- 188.20315880851746,
162
- 0.2804946561574936,
163
- 0.11371652073860168,
164
- 0.058778801321983334,
165
- 0.10474256777763366,
166
- 0.2396918488264084,
167
- 0.08152248692512512,
168
- 0.04248040814399719,
169
- 0.11303179881572724,
170
- 0.17326324067115784,
171
- 0.06998309404850006,
172
- 0.12122812910079957,
173
- 0.04671641788482666,
174
- 10.98456594619751,
175
- 1.0968475807189941,
176
- 1.6947754135131836,
177
- 0.03320046615600586,
178
- 1.3602827312469483,
179
- ],
180
- "std": [
181
- 1154.5919128300602,
182
- 0.5276998078079327,
183
- 0.7021637331734328,
184
- 0.36528892213195063,
185
- 0.17470213191865785,
186
- 0.20411195416718833,
187
- 0.0660782470089761,
188
- 0.03380702424871257,
189
- 0.09809195568521663,
190
- 0.11292471052124119,
191
- 0.09720748930233268,
192
- 0.12912217763726777,
193
- 0.0399973913151906,
194
- 23.725471823867462,
195
- 5.715238079725388,
196
- 9.030481416228302,
197
- 0.9950220242487364,
198
- 7.754429123862099,
199
- ],
200
- },
201
- }
202
 
203
 
204
  class MaskedOutput(NamedTuple):
@@ -257,7 +72,19 @@ def construct_galileo_input(
257
  latlon: torch.Tensor | None = None,
258
  months: torch.Tensor | None = None,
259
  normalize: bool = False,
 
260
  ) -> MaskedOutput:
 
 
 
 
 
 
 
 
 
 
 
261
  space_time_inputs = [s1, s2]
262
  time_inputs = [era5, tc, viirs]
263
  space_inputs = [srtm, dw, wc]
@@ -285,56 +112,56 @@ def construct_galileo_input(
285
  t = timesteps_list[0] if timesteps_list else 1
286
  h, w = (height_list[0], width_list[0]) if height_list else (1, 1)
287
 
288
- s_t_x = torch.zeros((h, w, t, len(SPACE_TIME_BANDS)), dtype=torch.float, device=device)
289
- s_t_m = torch.ones((h, w, t, len(SPACE_TIME_BANDS_GROUPS_IDX)), dtype=torch.float, device=device)
290
- sp_x = torch.zeros((h, w, len(SPACE_BANDS)), dtype=torch.float, device=device)
291
- sp_m = torch.ones((h, w, len(SPACE_BAND_GROUPS_IDX)), dtype=torch.float, device=device)
292
- t_x = torch.zeros((t, len(TIME_BANDS)), dtype=torch.float, device=device)
293
- t_m = torch.ones((t, len(TIME_BAND_GROUPS_IDX)), dtype=torch.float, device=device)
294
- st_x = torch.zeros((len(STATIC_BANDS)), dtype=torch.float, device=device)
295
- st_m = torch.ones((len(STATIC_BAND_GROUPS_IDX)), dtype=torch.float, device=device)
296
 
297
- for x, bands_list, group_key in zip([s1, s2], [S1_BANDS, S2_BANDS], ["S1", "S2"]):
298
  if x is not None:
299
- indices = [idx for idx, val in enumerate(SPACE_TIME_BANDS) if val in bands_list]
300
- groups_idx = [idx for idx, key in enumerate(SPACE_TIME_BANDS_GROUPS_IDX) if group_key in key]
301
  s_t_x[:, :, :, indices] = x
302
  s_t_m[:, :, :, groups_idx] = 0
303
 
304
  for x, bands_list, group_key in zip(
305
- [srtm, dw, wc], [SRTM_BANDS, DW_BANDS, WC_BANDS], ["SRTM", "DW", "WC"]
306
  ):
307
  if x is not None:
308
- indices = [idx for idx, val in enumerate(SPACE_BANDS) if val in bands_list]
309
- groups_idx = [idx for idx, key in enumerate(SPACE_BAND_GROUPS_IDX) if group_key in key]
310
  sp_x[:, :, indices] = x
311
  sp_m[:, :, groups_idx] = 0
312
 
313
  for x, bands_list, group_key in zip(
314
- [era5, tc, viirs], [ERA5_BANDS, TC_BANDS, VIIRS_BANDS], ["ERA5", "TC", "VIIRS"]
315
  ):
316
  if x is not None:
317
- indices = [idx for idx, val in enumerate(TIME_BANDS) if val in bands_list]
318
- groups_idx = [idx for idx, key in enumerate(TIME_BAND_GROUPS_IDX) if group_key in key]
319
  t_x[:, indices] = x
320
  t_m[:, groups_idx] = 0
321
 
322
  for x, bands_list, group_key in zip(
323
- [landscan, latlon], [LANDSCAN_BANDS, LOCATION_BANDS], ["LS", "location"]
324
  ):
325
  if x is not None:
326
  if group_key == "location":
327
  x = torch.as_tensor(to_cartesian(float(x[0]), float(x[1])), device=device)
328
- indices = [idx for idx, val in enumerate(STATIC_BANDS) if val in bands_list]
329
- groups_idx = [idx for idx, key in enumerate(STATIC_BAND_GROUPS_IDX) if group_key in key]
330
  st_x[indices] = x
331
  st_m[groups_idx] = 0
332
 
333
  if months is None:
334
- months = torch.ones((t), dtype=torch.long, device=device) * DEFAULT_MONTH
335
 
336
  if normalize:
337
- normalizer = PretrainingNormalizer(PRETRAINING_NORMALIZING_DICT)
338
  s_t_x = torch.from_numpy(normalizer(s_t_x.cpu().numpy())).to(device)
339
  sp_x = torch.from_numpy(normalizer(sp_x.cpu().numpy())).to(device)
340
  t_x = torch.from_numpy(normalizer(t_x.cpu().numpy())).to(device)
@@ -367,11 +194,48 @@ class GalileoProcessor(ProcessorMixin):
367
  "months",
368
  ]
369
 
370
- def __init__(self, normalize: bool = True, default_month: int = 6, patch_size: int = 8, **kwargs):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  super().__init__(**kwargs)
372
  self.normalize = normalize
373
  self.default_month = default_month
374
  self.patch_size = patch_size
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
 
376
  def __call__(
377
  self,
@@ -418,6 +282,7 @@ class GalileoProcessor(ProcessorMixin):
418
  latlon=_to_tensor(latlon),
419
  months=months,
420
  normalize=normalize,
 
421
  )
422
 
423
  if masked_output.space_time_x.dim() == 4:
 
4
  from __future__ import annotations
5
 
6
  import math
 
7
  from typing import Any, NamedTuple, Optional, Union
8
 
9
  import numpy as np
 
13
  from transformers.processing_utils import ProcessorMixin
14
  from transformers.utils import TensorType
15
 
16
+ from .modeling_galileo import GalileoConfig
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
 
19
  class MaskedOutput(NamedTuple):
 
72
  latlon: torch.Tensor | None = None,
73
  months: torch.Tensor | None = None,
74
  normalize: bool = False,
75
+ band_config: GalileoConfig | None = None,
76
  ) -> MaskedOutput:
77
+ band_config = band_config or GalileoConfig()
78
+ bands = band_config.band_layout()
79
+ space_time_bands = bands["space_time_bands"]
80
+ space_time_groups = bands["space_time_groups"]
81
+ time_bands = bands["time_bands"]
82
+ time_groups = bands["time_groups"]
83
+ space_bands = bands["space_bands"]
84
+ space_groups = bands["space_groups"]
85
+ static_bands = bands["static_bands"]
86
+ static_groups = bands["static_groups"]
87
+
88
  space_time_inputs = [s1, s2]
89
  time_inputs = [era5, tc, viirs]
90
  space_inputs = [srtm, dw, wc]
 
112
  t = timesteps_list[0] if timesteps_list else 1
113
  h, w = (height_list[0], width_list[0]) if height_list else (1, 1)
114
 
115
+ s_t_x = torch.zeros((h, w, t, len(space_time_bands)), dtype=torch.float, device=device)
116
+ s_t_m = torch.ones((h, w, t, len(space_time_groups)), dtype=torch.float, device=device)
117
+ sp_x = torch.zeros((h, w, len(space_bands)), dtype=torch.float, device=device)
118
+ sp_m = torch.ones((h, w, len(space_groups)), dtype=torch.float, device=device)
119
+ t_x = torch.zeros((t, len(time_bands)), dtype=torch.float, device=device)
120
+ t_m = torch.ones((t, len(time_groups)), dtype=torch.float, device=device)
121
+ st_x = torch.zeros((len(static_bands)), dtype=torch.float, device=device)
122
+ st_m = torch.ones((len(static_groups)), dtype=torch.float, device=device)
123
 
124
+ for x, bands_list, group_key in zip([s1, s2], [bands["s1_bands"], bands["s2_bands"]], ["S1", "S2"]):
125
  if x is not None:
126
+ indices = [idx for idx, val in enumerate(space_time_bands) if val in bands_list]
127
+ groups_idx = [idx for idx, key in enumerate(space_time_groups) if group_key in key]
128
  s_t_x[:, :, :, indices] = x
129
  s_t_m[:, :, :, groups_idx] = 0
130
 
131
  for x, bands_list, group_key in zip(
132
+ [srtm, dw, wc], [bands["srtm_bands"], bands["dw_bands"], bands["wc_bands"]], ["SRTM", "DW", "WC"]
133
  ):
134
  if x is not None:
135
+ indices = [idx for idx, val in enumerate(space_bands) if val in bands_list]
136
+ groups_idx = [idx for idx, key in enumerate(space_groups) if group_key in key]
137
  sp_x[:, :, indices] = x
138
  sp_m[:, :, groups_idx] = 0
139
 
140
  for x, bands_list, group_key in zip(
141
+ [era5, tc, viirs], [bands["era5_bands"], bands["tc_bands"], bands["viirs_bands"]], ["ERA5", "TC", "VIIRS"]
142
  ):
143
  if x is not None:
144
+ indices = [idx for idx, val in enumerate(time_bands) if val in bands_list]
145
+ groups_idx = [idx for idx, key in enumerate(time_groups) if group_key in key]
146
  t_x[:, indices] = x
147
  t_m[:, groups_idx] = 0
148
 
149
  for x, bands_list, group_key in zip(
150
+ [landscan, latlon], [bands["landscan_bands"], bands["location_bands"]], ["LS", "location"]
151
  ):
152
  if x is not None:
153
  if group_key == "location":
154
  x = torch.as_tensor(to_cartesian(float(x[0]), float(x[1])), device=device)
155
+ indices = [idx for idx, val in enumerate(static_bands) if val in bands_list]
156
+ groups_idx = [idx for idx, key in enumerate(static_groups) if group_key in key]
157
  st_x[indices] = x
158
  st_m[groups_idx] = 0
159
 
160
  if months is None:
161
+ months = torch.ones((t), dtype=torch.long, device=device) * band_config.default_month
162
 
163
  if normalize:
164
+ normalizer = PretrainingNormalizer(band_config.pretraining_normalizing_dict)
165
  s_t_x = torch.from_numpy(normalizer(s_t_x.cpu().numpy())).to(device)
166
  sp_x = torch.from_numpy(normalizer(sp_x.cpu().numpy())).to(device)
167
  t_x = torch.from_numpy(normalizer(t_x.cpu().numpy())).to(device)
 
194
  "months",
195
  ]
196
 
197
+ def __init__(
198
+ self,
199
+ normalize: bool = True,
200
+ default_month: int = 6,
201
+ patch_size: int = 8,
202
+ s1_bands: Optional[list[str]] = None,
203
+ s2_bands: Optional[list[str]] = None,
204
+ era5_bands: Optional[list[str]] = None,
205
+ tc_bands: Optional[list[str]] = None,
206
+ viirs_bands: Optional[list[str]] = None,
207
+ srtm_bands: Optional[list[str]] = None,
208
+ dw_bands: Optional[list[str]] = None,
209
+ wc_bands: Optional[list[str]] = None,
210
+ landscan_bands: Optional[list[str]] = None,
211
+ location_bands: Optional[list[str]] = None,
212
+ space_time_band_groups: Optional[dict[str, list[str]]] = None,
213
+ time_band_groups: Optional[dict[str, list[str]]] = None,
214
+ space_band_groups: Optional[dict[str, list[str]]] = None,
215
+ pretraining_normalizing_dict: Optional[dict[str, dict[str, list[float]]]] = None,
216
+ **kwargs,
217
+ ):
218
  super().__init__(**kwargs)
219
  self.normalize = normalize
220
  self.default_month = default_month
221
  self.patch_size = patch_size
222
+ self.band_config = GalileoConfig(
223
+ default_month=default_month,
224
+ s1_bands=s1_bands,
225
+ s2_bands=s2_bands,
226
+ era5_bands=era5_bands,
227
+ tc_bands=tc_bands,
228
+ viirs_bands=viirs_bands,
229
+ srtm_bands=srtm_bands,
230
+ dw_bands=dw_bands,
231
+ wc_bands=wc_bands,
232
+ landscan_bands=landscan_bands,
233
+ location_bands=location_bands,
234
+ space_time_band_groups=space_time_band_groups,
235
+ time_band_groups=time_band_groups,
236
+ space_band_groups=space_band_groups,
237
+ pretraining_normalizing_dict=pretraining_normalizing_dict,
238
+ )
239
 
240
  def __call__(
241
  self,
 
282
  latlon=_to_tensor(latlon),
283
  months=months,
284
  normalize=normalize,
285
+ band_config=self.band_config,
286
  )
287
 
288
  if masked_output.space_time_x.dim() == 4:
galileo-tiny-patch8/__pycache__/modeling_galileo.cpython-311.pyc ADDED
Binary file (65.5 kB). View file
 
galileo-tiny-patch8/__pycache__/modeling_galileo.cpython-39.pyc ADDED
Binary file (33.5 kB). View file
 
galileo-tiny-patch8/config.json CHANGED
@@ -43,5 +43,262 @@
43
  "AutoModel"
44
  ]
45
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
- }
 
43
  "AutoModel"
44
  ]
45
  }
46
+ },
47
+ "s1_bands": [
48
+ "VV",
49
+ "VH"
50
+ ],
51
+ "s2_bands": [
52
+ "B2",
53
+ "B3",
54
+ "B4",
55
+ "B5",
56
+ "B6",
57
+ "B7",
58
+ "B8",
59
+ "B8A",
60
+ "B11",
61
+ "B12"
62
+ ],
63
+ "era5_bands": [
64
+ "temperature_2m",
65
+ "total_precipitation_sum"
66
+ ],
67
+ "tc_bands": [
68
+ "def",
69
+ "soil",
70
+ "aet"
71
+ ],
72
+ "viirs_bands": [
73
+ "avg_rad"
74
+ ],
75
+ "srtm_bands": [
76
+ "elevation",
77
+ "slope"
78
+ ],
79
+ "dw_bands": [
80
+ "DW_water",
81
+ "DW_trees",
82
+ "DW_grass",
83
+ "DW_flooded_vegetation",
84
+ "DW_crops",
85
+ "DW_shrub_and_scrub",
86
+ "DW_built",
87
+ "DW_bare",
88
+ "DW_snow_and_ice"
89
+ ],
90
+ "wc_bands": [
91
+ "WC_temporarycrops",
92
+ "WC_maize",
93
+ "WC_wintercereals",
94
+ "WC_springcereals",
95
+ "WC_irrigation"
96
+ ],
97
+ "landscan_bands": [
98
+ "b1"
99
+ ],
100
+ "location_bands": [
101
+ "x",
102
+ "y",
103
+ "z"
104
+ ],
105
+ "space_time_band_groups": {
106
+ "S1": [
107
+ "VV",
108
+ "VH"
109
+ ],
110
+ "S2_RGB": [
111
+ "B2",
112
+ "B3",
113
+ "B4"
114
+ ],
115
+ "S2_Red_Edge": [
116
+ "B5",
117
+ "B6",
118
+ "B7"
119
+ ],
120
+ "S2_NIR_10m": [
121
+ "B8"
122
+ ],
123
+ "S2_NIR_20m": [
124
+ "B8A"
125
+ ],
126
+ "S2_SWIR": [
127
+ "B11",
128
+ "B12"
129
+ ],
130
+ "NDVI": [
131
+ "NDVI"
132
+ ]
133
+ },
134
+ "time_band_groups": {
135
+ "ERA5": [
136
+ "temperature_2m",
137
+ "total_precipitation_sum"
138
+ ],
139
+ "TC": [
140
+ "def",
141
+ "soil",
142
+ "aet"
143
+ ],
144
+ "VIIRS": [
145
+ "avg_rad"
146
+ ]
147
+ },
148
+ "space_band_groups": {
149
+ "SRTM": [
150
+ "elevation",
151
+ "slope"
152
+ ],
153
+ "DW": [
154
+ "DW_water",
155
+ "DW_trees",
156
+ "DW_grass",
157
+ "DW_flooded_vegetation",
158
+ "DW_crops",
159
+ "DW_shrub_and_scrub",
160
+ "DW_built",
161
+ "DW_bare",
162
+ "DW_snow_and_ice"
163
+ ],
164
+ "WC": [
165
+ "WC_temporarycrops",
166
+ "WC_maize",
167
+ "WC_wintercereals",
168
+ "WC_springcereals",
169
+ "WC_irrigation"
170
+ ]
171
+ },
172
+ "pretraining_normalizing_dict": {
173
+ "13": {
174
+ "mean": [
175
+ -11.728724389184965,
176
+ -18.85558188024017,
177
+ 1395.3408730676722,
178
+ 1338.4026921784578,
179
+ 1343.09883810357,
180
+ 1543.8607982512297,
181
+ 2186.2022069512263,
182
+ 2525.0932853316694,
183
+ 2410.3377187373408,
184
+ 2750.2854646886753,
185
+ 2234.911100061487,
186
+ 1474.5311266077113,
187
+ 0.2892116502999044
188
+ ],
189
+ "std": [
190
+ 4.887145774840316,
191
+ 5.730270320384293,
192
+ 917.7041440370853,
193
+ 913.2988423581528,
194
+ 1092.678723527555,
195
+ 1047.2206083460424,
196
+ 1048.0101611156767,
197
+ 1143.6903026819996,
198
+ 1098.979177731649,
199
+ 1204.472755085893,
200
+ 1145.9774063078878,
201
+ 980.2429840007796,
202
+ 0.2720939024500081
203
+ ]
204
+ },
205
+ "16": {
206
+ "mean": [
207
+ 673.0152819503361,
208
+ 5.930092668915115,
209
+ 0.10470439140978786,
210
+ 0.23965913270066183,
211
+ 0.08158044385860364,
212
+ 0.04246976254259546,
213
+ 0.11304392863520317,
214
+ 0.17329647890362473,
215
+ 0.0698981691616277,
216
+ 0.12130267132802142,
217
+ 0.04671318615236216,
218
+ 10.973119802517362,
219
+ 1.0927069179958768,
220
+ 1.6991394232855903,
221
+ 0.03720594618055555,
222
+ 1.3671352688259548
223
+ ],
224
+ "std": [
225
+ 983.0697298296237,
226
+ 8.167406789813247,
227
+ 0.18771647977504985,
228
+ 0.2368313455675914,
229
+ 0.08024268534756586,
230
+ 0.04045374496146404,
231
+ 0.11350342472061795,
232
+ 0.1279898111718168,
233
+ 0.12042341550438586,
234
+ 0.13602408145504347,
235
+ 0.043971116096060345,
236
+ 31.255340146970997,
237
+ 10.395974878206689,
238
+ 12.92380617159917,
239
+ 1.9285254295940466,
240
+ 11.612179775408928
241
+ ]
242
+ },
243
+ "6": {
244
+ "mean": [
245
+ 271.5674963541667,
246
+ 0.08554303677156568,
247
+ 657.3181260091111,
248
+ 692.1291795806885,
249
+ 562.781331880633,
250
+ 1.5647115934036673
251
+ ],
252
+ "std": [
253
+ 79.80828940314429,
254
+ 0.11669547098151486,
255
+ 704.0008695557707,
256
+ 925.0116126406431,
257
+ 453.2434022278578,
258
+ 7.513020170832818
259
+ ]
260
+ },
261
+ "18": {
262
+ "mean": [
263
+ 188.20315880851746,
264
+ 0.2804946561574936,
265
+ 0.11371652073860168,
266
+ 0.058778801321983334,
267
+ 0.10474256777763366,
268
+ 0.2396918488264084,
269
+ 0.08152248692512512,
270
+ 0.04248040814399719,
271
+ 0.11303179881572724,
272
+ 0.17326324067115784,
273
+ 0.06998309404850006,
274
+ 0.12122812910079957,
275
+ 0.04671641788482666,
276
+ 10.98456594619751,
277
+ 1.0968475807189941,
278
+ 1.6947754135131836,
279
+ 0.03320046615600586,
280
+ 1.3602827312469483
281
+ ],
282
+ "std": [
283
+ 1154.5919128300602,
284
+ 0.5276998078079327,
285
+ 0.7021637331734328,
286
+ 0.36528892213195063,
287
+ 0.17470213191865785,
288
+ 0.20411195416718833,
289
+ 0.0660782470089761,
290
+ 0.03380702424871257,
291
+ 0.09809195568521663,
292
+ 0.11292471052124119,
293
+ 0.09720748930233268,
294
+ 0.12912217763726777,
295
+ 0.0399973913151906,
296
+ 23.725471823867462,
297
+ 5.715238079725388,
298
+ 9.030481416228302,
299
+ 0.9950220242487364,
300
+ 7.754429123862099
301
+ ]
302
+ }
303
  }
304
+ }
galileo-tiny-patch8/modeling_galileo.py CHANGED
@@ -26,95 +26,11 @@ from einops import rearrange, repeat
26
  from torch import Tensor, vmap
27
  from torch.jit import Final
28
 
29
- # constants
30
- CONFIG_FILENAME = "config.json"
31
- ENCODER_FILENAME = "encoder.pt"
32
- BASE_GSD = 10
33
-
34
- # band information
35
- S1_BANDS = ["VV", "VH"]
36
- S2_BANDS = [
37
- "B2",
38
- "B3",
39
- "B4",
40
- "B5",
41
- "B6",
42
- "B7",
43
- "B8",
44
- "B8A",
45
- "B11",
46
- "B12",
47
- ]
48
- ERA5_BANDS = ["temperature_2m", "total_precipitation_sum"]
49
- TC_BANDS = ["def", "soil", "aet"]
50
- VIIRS_BANDS = ["avg_rad"]
51
- SRTM_BANDS = ["elevation", "slope"]
52
- DW_BANDS = [
53
- "DW_water",
54
- "DW_trees",
55
- "DW_grass",
56
- "DW_flooded_vegetation",
57
- "DW_crops",
58
- "DW_shrub_and_scrub",
59
- "DW_built",
60
- "DW_bare",
61
- "DW_snow_and_ice",
62
- ]
63
- WC_BANDS = [
64
- "WC_temporarycrops",
65
- "WC_maize",
66
- "WC_wintercereals",
67
- "WC_springcereals",
68
- "WC_irrigation",
69
- ]
70
- STATIC_DW_BANDS = [f"{x}_static" for x in DW_BANDS]
71
- STATIC_WC_BANDS = [f"{x}_static" for x in WC_BANDS]
72
-
73
- LANDSCAN_BANDS = ["b1"]
74
- LOCATION_BANDS = ["x", "y", "z"]
75
-
76
- SPACE_TIME_BANDS = S1_BANDS + S2_BANDS + ["NDVI"]
77
- TIME_BANDS = ERA5_BANDS + TC_BANDS + VIIRS_BANDS
78
- SPACE_BANDS = SRTM_BANDS + DW_BANDS + WC_BANDS
79
- STATIC_BANDS = LANDSCAN_BANDS + LOCATION_BANDS + STATIC_DW_BANDS + STATIC_WC_BANDS
80
-
81
-
82
- SPACE_TIME_BANDS_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
83
- {
84
- "S1": [SPACE_TIME_BANDS.index(b) for b in S1_BANDS],
85
- "S2_RGB": [SPACE_TIME_BANDS.index(b) for b in ["B2", "B3", "B4"]],
86
- "S2_Red_Edge": [SPACE_TIME_BANDS.index(b) for b in ["B5", "B6", "B7"]],
87
- "S2_NIR_10m": [SPACE_TIME_BANDS.index(b) for b in ["B8"]],
88
- "S2_NIR_20m": [SPACE_TIME_BANDS.index(b) for b in ["B8A"]],
89
- "S2_SWIR": [SPACE_TIME_BANDS.index(b) for b in ["B11", "B12"]],
90
- "NDVI": [SPACE_TIME_BANDS.index("NDVI")],
91
- }
92
- )
93
-
94
- TIME_BAND_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
95
- {
96
- "ERA5": [TIME_BANDS.index(b) for b in ERA5_BANDS],
97
- "TC": [TIME_BANDS.index(b) for b in TC_BANDS],
98
- "VIIRS": [TIME_BANDS.index(b) for b in VIIRS_BANDS],
99
- }
100
- )
101
 
102
- SPACE_BAND_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
103
- {
104
- "SRTM": [SPACE_BANDS.index(b) for b in SRTM_BANDS],
105
- "DW": [SPACE_BANDS.index(b) for b in DW_BANDS],
106
- "WC": [SPACE_BANDS.index(b) for b in WC_BANDS],
107
- }
108
- )
109
-
110
- STATIC_BAND_GROUPS_IDX: OrderedDictType[str, List[int]] = OrderedDict(
111
- {
112
- "LS": [STATIC_BANDS.index(b) for b in LANDSCAN_BANDS],
113
- "location": [STATIC_BANDS.index(b) for b in LOCATION_BANDS],
114
- "DW_static": [STATIC_BANDS.index(b) for b in STATIC_DW_BANDS],
115
- "WC_static": [STATIC_BANDS.index(b) for b in STATIC_WC_BANDS],
116
- }
117
- )
118
 
119
 
120
  def get_2d_sincos_pos_embed_with_resolution(
@@ -565,13 +481,16 @@ class GalileoBase(nn.Module):
565
  base_patch_size: int = 4,
566
  use_channel_embs: bool = True,
567
  drop_path: float = 0.0,
 
568
  ):
569
  super().__init__()
570
 
571
- self.space_time_groups = SPACE_TIME_BANDS_GROUPS_IDX
572
- self.space_groups = SPACE_BAND_GROUPS_IDX
573
- self.time_groups = TIME_BAND_GROUPS_IDX
574
- self.static_groups = STATIC_BAND_GROUPS_IDX
 
 
575
  self.embedding_size = embedding_size
576
  self.base_patch_size = base_patch_size
577
 
@@ -606,16 +525,16 @@ class GalileoBase(nn.Module):
606
  else:
607
  args = {"requires_grad": False}
608
  self.s_t_channel_embed = nn.Parameter(
609
- torch.zeros(len(SPACE_TIME_BANDS_GROUPS_IDX), int(embedding_size * 0.25)), **args
610
  )
611
  self.sp_channel_embed = nn.Parameter(
612
- torch.zeros(len(SPACE_BAND_GROUPS_IDX), int(embedding_size * 0.25)), **args
613
  )
614
  self.t_channel_embed = nn.Parameter(
615
- torch.zeros(len(TIME_BAND_GROUPS_IDX), int(embedding_size * 0.25)), **args
616
  )
617
  self.st_channel_embed = nn.Parameter(
618
- torch.zeros(len(STATIC_BAND_GROUPS_IDX), int(embedding_size * 0.25)), **args
619
  )
620
 
621
  self.apply(self._init_weights)
@@ -720,7 +639,7 @@ class GalileoBase(nn.Module):
720
  if patch_size is None:
721
  patch_size = self.base_patch_size
722
  token_res = input_res * patch_size
723
- gsd_ratio = token_res / BASE_GSD
724
 
725
  assert h == w, "get_2d_sincos_pos_embed_with_resolution currently requires that h==w"
726
  spatial_embed = get_2d_sincos_pos_embed_with_resolution(
@@ -755,6 +674,7 @@ class Encoder(GalileoBase):
755
  max_sequence_length=24,
756
  freeze_projections: bool = False,
757
  drop_path: float = 0.0,
 
758
  ):
759
  super().__init__(
760
  embedding_size,
@@ -765,6 +685,7 @@ class Encoder(GalileoBase):
765
  max_patch_size,
766
  use_channel_embs=True,
767
  drop_path=drop_path,
 
768
  )
769
 
770
  self.space_time_embed = nn.ModuleDict(
@@ -1108,11 +1029,14 @@ class Encoder(GalileoBase):
1108
  st_m: torch.Tensor,
1109
  months: torch.Tensor,
1110
  patch_size: int,
1111
- input_resolution_m: Optional[int] = BASE_GSD,
1112
  exit_after: Optional[int] = None,
1113
  token_exit_cfg: Optional[Dict] = None,
1114
  add_layernorm_on_exit: bool = True,
1115
  ):
 
 
 
1116
  (
1117
  s_t_x,
1118
  sp_x,
@@ -1161,25 +1085,31 @@ class Encoder(GalileoBase):
1161
  )
1162
 
1163
  @classmethod
1164
- def load_from_folder(cls, folder: Path, device: torch.device):
1165
- if not (folder / CONFIG_FILENAME).exists():
 
 
 
 
 
 
1166
  all_files_in_folder = [f.name for f in folder.glob("*")]
1167
  raise ValueError(
1168
- f"Expected {CONFIG_FILENAME} in {folder}, found {all_files_in_folder}"
1169
  )
1170
- if not (folder / ENCODER_FILENAME).exists():
1171
  all_files_in_folder = [f.name for f in folder.glob("*")]
1172
  raise ValueError(
1173
- f"Expected {ENCODER_FILENAME} in {folder}, found {all_files_in_folder}"
1174
  )
1175
 
1176
- with (folder / CONFIG_FILENAME).open("r") as f:
1177
  config = json.load(f)
1178
  model_config = config["model"]
1179
  encoder_config = model_config["encoder"]
1180
  encoder = cls(**encoder_config)
1181
 
1182
- state_dict = torch.load(folder / ENCODER_FILENAME, map_location=device)
1183
  for key in list(state_dict.keys()):
1184
  # this cleans the state dict, which occasionally had an extra
1185
  # ".backbone" included in the key names
@@ -1189,6 +1119,141 @@ class Encoder(GalileoBase):
1189
  logger = logging.get_logger(__name__)
1190
 
1191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1192
  class GalileoConfig(PreTrainedConfig):
1193
  model_type = "galileo"
1194
 
@@ -1206,6 +1271,20 @@ class GalileoConfig(PreTrainedConfig):
1206
  default_month: int = 6,
1207
  global_pool: bool = True,
1208
  input_resolution_m: int = 10,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1209
  **kwargs,
1210
  ):
1211
  super().__init__(**kwargs)
@@ -1221,6 +1300,89 @@ class GalileoConfig(PreTrainedConfig):
1221
  self.default_month = default_month
1222
  self.global_pool = global_pool
1223
  self.input_resolution_m = input_resolution_m
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1224
 
1225
 
1226
  class GalileoPreTrainedModel(PreTrainedModel):
@@ -1245,6 +1407,7 @@ class GalileoEncoderModel(GalileoPreTrainedModel):
1245
  max_sequence_length=config.max_sequence_length,
1246
  freeze_projections=config.freeze_projections,
1247
  drop_path=config.drop_path,
 
1248
  )
1249
  self.add_pooling_layer = add_pooling_layer and config.global_pool
1250
  self.post_init()
 
26
  from torch import Tensor, vmap
27
  from torch.jit import Final
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ def _band_group_indices(
31
+ bands: Sequence[str], groups: Dict[str, List[str]]
32
+ ) -> OrderedDictType[str, List[int]]:
33
+ return OrderedDict((name, [bands.index(b) for b in group_bands]) for name, group_bands in groups.items())
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
 
36
  def get_2d_sincos_pos_embed_with_resolution(
 
481
  base_patch_size: int = 4,
482
  use_channel_embs: bool = True,
483
  drop_path: float = 0.0,
484
+ band_layout: Optional[Dict[str, Any]] = None,
485
  ):
486
  super().__init__()
487
 
488
+ band_layout = band_layout or GalileoConfig().band_layout()
489
+ self.space_time_groups = band_layout["space_time_groups"]
490
+ self.space_groups = band_layout["space_groups"]
491
+ self.time_groups = band_layout["time_groups"]
492
+ self.static_groups = band_layout["static_groups"]
493
+ self.base_gsd = band_layout["input_resolution_m"]
494
  self.embedding_size = embedding_size
495
  self.base_patch_size = base_patch_size
496
 
 
525
  else:
526
  args = {"requires_grad": False}
527
  self.s_t_channel_embed = nn.Parameter(
528
+ torch.zeros(len(self.space_time_groups), int(embedding_size * 0.25)), **args
529
  )
530
  self.sp_channel_embed = nn.Parameter(
531
+ torch.zeros(len(self.space_groups), int(embedding_size * 0.25)), **args
532
  )
533
  self.t_channel_embed = nn.Parameter(
534
+ torch.zeros(len(self.time_groups), int(embedding_size * 0.25)), **args
535
  )
536
  self.st_channel_embed = nn.Parameter(
537
+ torch.zeros(len(self.static_groups), int(embedding_size * 0.25)), **args
538
  )
539
 
540
  self.apply(self._init_weights)
 
639
  if patch_size is None:
640
  patch_size = self.base_patch_size
641
  token_res = input_res * patch_size
642
+ gsd_ratio = token_res / self.base_gsd
643
 
644
  assert h == w, "get_2d_sincos_pos_embed_with_resolution currently requires that h==w"
645
  spatial_embed = get_2d_sincos_pos_embed_with_resolution(
 
674
  max_sequence_length=24,
675
  freeze_projections: bool = False,
676
  drop_path: float = 0.0,
677
+ band_layout: Optional[Dict[str, Any]] = None,
678
  ):
679
  super().__init__(
680
  embedding_size,
 
685
  max_patch_size,
686
  use_channel_embs=True,
687
  drop_path=drop_path,
688
+ band_layout=band_layout,
689
  )
690
 
691
  self.space_time_embed = nn.ModuleDict(
 
1029
  st_m: torch.Tensor,
1030
  months: torch.Tensor,
1031
  patch_size: int,
1032
+ input_resolution_m: Optional[int] = None,
1033
  exit_after: Optional[int] = None,
1034
  token_exit_cfg: Optional[Dict] = None,
1035
  add_layernorm_on_exit: bool = True,
1036
  ):
1037
+ if input_resolution_m is None:
1038
+ input_resolution_m = self.base_gsd
1039
+
1040
  (
1041
  s_t_x,
1042
  sp_x,
 
1085
  )
1086
 
1087
  @classmethod
1088
+ def load_from_folder(
1089
+ cls,
1090
+ folder: Path,
1091
+ device: torch.device,
1092
+ config_filename: str = "config.json",
1093
+ encoder_filename: str = "encoder.pt",
1094
+ ):
1095
+ if not (folder / config_filename).exists():
1096
  all_files_in_folder = [f.name for f in folder.glob("*")]
1097
  raise ValueError(
1098
+ f"Expected {config_filename} in {folder}, found {all_files_in_folder}"
1099
  )
1100
+ if not (folder / encoder_filename).exists():
1101
  all_files_in_folder = [f.name for f in folder.glob("*")]
1102
  raise ValueError(
1103
+ f"Expected {encoder_filename} in {folder}, found {all_files_in_folder}"
1104
  )
1105
 
1106
+ with (folder / config_filename).open("r") as f:
1107
  config = json.load(f)
1108
  model_config = config["model"]
1109
  encoder_config = model_config["encoder"]
1110
  encoder = cls(**encoder_config)
1111
 
1112
+ state_dict = torch.load(folder / encoder_filename, map_location=device)
1113
  for key in list(state_dict.keys()):
1114
  # this cleans the state dict, which occasionally had an extra
1115
  # ".backbone" included in the key names
 
1119
  logger = logging.get_logger(__name__)
1120
 
1121
 
1122
+ def _default_pretraining_normalizing_dict() -> Dict[str, Dict[str, List[float]]]:
1123
+ return {
1124
+ "13": {
1125
+ "mean": [
1126
+ -11.728724389184965,
1127
+ -18.85558188024017,
1128
+ 1395.3408730676722,
1129
+ 1338.4026921784578,
1130
+ 1343.09883810357,
1131
+ 1543.8607982512297,
1132
+ 2186.2022069512263,
1133
+ 2525.0932853316694,
1134
+ 2410.3377187373408,
1135
+ 2750.2854646886753,
1136
+ 2234.911100061487,
1137
+ 1474.5311266077113,
1138
+ 0.2892116502999044,
1139
+ ],
1140
+ "std": [
1141
+ 4.887145774840316,
1142
+ 5.730270320384293,
1143
+ 917.7041440370853,
1144
+ 913.2988423581528,
1145
+ 1092.678723527555,
1146
+ 1047.2206083460424,
1147
+ 1048.0101611156767,
1148
+ 1143.6903026819996,
1149
+ 1098.979177731649,
1150
+ 1204.472755085893,
1151
+ 1145.9774063078878,
1152
+ 980.2429840007796,
1153
+ 0.2720939024500081,
1154
+ ],
1155
+ },
1156
+ "16": {
1157
+ "mean": [
1158
+ 673.0152819503361,
1159
+ 5.930092668915115,
1160
+ 0.10470439140978786,
1161
+ 0.23965913270066183,
1162
+ 0.08158044385860364,
1163
+ 0.04246976254259546,
1164
+ 0.11304392863520317,
1165
+ 0.17329647890362473,
1166
+ 0.0698981691616277,
1167
+ 0.12130267132802142,
1168
+ 0.04671318615236216,
1169
+ 10.973119802517362,
1170
+ 1.0927069179958768,
1171
+ 1.6991394232855903,
1172
+ 0.03720594618055555,
1173
+ 1.3671352688259548,
1174
+ ],
1175
+ "std": [
1176
+ 983.0697298296237,
1177
+ 8.167406789813247,
1178
+ 0.18771647977504985,
1179
+ 0.2368313455675914,
1180
+ 0.08024268534756586,
1181
+ 0.04045374496146404,
1182
+ 0.11350342472061795,
1183
+ 0.1279898111718168,
1184
+ 0.12042341550438586,
1185
+ 0.13602408145504347,
1186
+ 0.043971116096060345,
1187
+ 31.255340146970997,
1188
+ 10.395974878206689,
1189
+ 12.92380617159917,
1190
+ 1.9285254295940466,
1191
+ 11.612179775408928,
1192
+ ],
1193
+ },
1194
+ "6": {
1195
+ "mean": [
1196
+ 271.5674963541667,
1197
+ 0.08554303677156568,
1198
+ 657.3181260091111,
1199
+ 692.1291795806885,
1200
+ 562.781331880633,
1201
+ 1.5647115934036673,
1202
+ ],
1203
+ "std": [
1204
+ 79.80828940314429,
1205
+ 0.11669547098151486,
1206
+ 704.0008695557707,
1207
+ 925.0116126406431,
1208
+ 453.2434022278578,
1209
+ 7.513020170832818,
1210
+ ],
1211
+ },
1212
+ "18": {
1213
+ "mean": [
1214
+ 188.20315880851746,
1215
+ 0.2804946561574936,
1216
+ 0.11371652073860168,
1217
+ 0.058778801321983334,
1218
+ 0.10474256777763366,
1219
+ 0.2396918488264084,
1220
+ 0.08152248692512512,
1221
+ 0.04248040814399719,
1222
+ 0.11303179881572724,
1223
+ 0.17326324067115784,
1224
+ 0.06998309404850006,
1225
+ 0.12122812910079957,
1226
+ 0.04671641788482666,
1227
+ 10.98456594619751,
1228
+ 1.0968475807189941,
1229
+ 1.6947754135131836,
1230
+ 0.03320046615600586,
1231
+ 1.3602827312469483,
1232
+ ],
1233
+ "std": [
1234
+ 1154.5919128300602,
1235
+ 0.5276998078079327,
1236
+ 0.7021637331734328,
1237
+ 0.36528892213195063,
1238
+ 0.17470213191865785,
1239
+ 0.20411195416718833,
1240
+ 0.0660782470089761,
1241
+ 0.03380702424871257,
1242
+ 0.09809195568521663,
1243
+ 0.11292471052124119,
1244
+ 0.09720748930233268,
1245
+ 0.12912217763726777,
1246
+ 0.0399973913151906,
1247
+ 23.725471823867462,
1248
+ 5.715238079725388,
1249
+ 9.030481416228302,
1250
+ 0.9950220242487364,
1251
+ 7.754429123862099,
1252
+ ],
1253
+ },
1254
+ }
1255
+
1256
+
1257
  class GalileoConfig(PreTrainedConfig):
1258
  model_type = "galileo"
1259
 
 
1271
  default_month: int = 6,
1272
  global_pool: bool = True,
1273
  input_resolution_m: int = 10,
1274
+ s1_bands: Optional[List[str]] = None,
1275
+ s2_bands: Optional[List[str]] = None,
1276
+ era5_bands: Optional[List[str]] = None,
1277
+ tc_bands: Optional[List[str]] = None,
1278
+ viirs_bands: Optional[List[str]] = None,
1279
+ srtm_bands: Optional[List[str]] = None,
1280
+ dw_bands: Optional[List[str]] = None,
1281
+ wc_bands: Optional[List[str]] = None,
1282
+ landscan_bands: Optional[List[str]] = None,
1283
+ location_bands: Optional[List[str]] = None,
1284
+ space_time_band_groups: Optional[Dict[str, List[str]]] = None,
1285
+ time_band_groups: Optional[Dict[str, List[str]]] = None,
1286
+ space_band_groups: Optional[Dict[str, List[str]]] = None,
1287
+ pretraining_normalizing_dict: Optional[Dict[str, Dict[str, List[float]]]] = None,
1288
  **kwargs,
1289
  ):
1290
  super().__init__(**kwargs)
 
1300
  self.default_month = default_month
1301
  self.global_pool = global_pool
1302
  self.input_resolution_m = input_resolution_m
1303
+ self.s1_bands = s1_bands if s1_bands is not None else ["VV", "VH"]
1304
+ self.s2_bands = s2_bands if s2_bands is not None else [
1305
+ "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B8A", "B11", "B12",
1306
+ ]
1307
+ self.era5_bands = era5_bands if era5_bands is not None else [
1308
+ "temperature_2m", "total_precipitation_sum",
1309
+ ]
1310
+ self.tc_bands = tc_bands if tc_bands is not None else ["def", "soil", "aet"]
1311
+ self.viirs_bands = viirs_bands if viirs_bands is not None else ["avg_rad"]
1312
+ self.srtm_bands = srtm_bands if srtm_bands is not None else ["elevation", "slope"]
1313
+ self.dw_bands = dw_bands if dw_bands is not None else [
1314
+ "DW_water", "DW_trees", "DW_grass", "DW_flooded_vegetation", "DW_crops",
1315
+ "DW_shrub_and_scrub", "DW_built", "DW_bare", "DW_snow_and_ice",
1316
+ ]
1317
+ self.wc_bands = wc_bands if wc_bands is not None else [
1318
+ "WC_temporarycrops", "WC_maize", "WC_wintercereals", "WC_springcereals", "WC_irrigation",
1319
+ ]
1320
+ self.landscan_bands = landscan_bands if landscan_bands is not None else ["b1"]
1321
+ self.location_bands = location_bands if location_bands is not None else ["x", "y", "z"]
1322
+ self.space_time_band_groups = space_time_band_groups if space_time_band_groups is not None else {
1323
+ "S1": ["VV", "VH"],
1324
+ "S2_RGB": ["B2", "B3", "B4"],
1325
+ "S2_Red_Edge": ["B5", "B6", "B7"],
1326
+ "S2_NIR_10m": ["B8"],
1327
+ "S2_NIR_20m": ["B8A"],
1328
+ "S2_SWIR": ["B11", "B12"],
1329
+ "NDVI": ["NDVI"],
1330
+ }
1331
+ self.time_band_groups = time_band_groups if time_band_groups is not None else {
1332
+ "ERA5": ["temperature_2m", "total_precipitation_sum"],
1333
+ "TC": ["def", "soil", "aet"],
1334
+ "VIIRS": ["avg_rad"],
1335
+ }
1336
+ self.space_band_groups = space_band_groups if space_band_groups is not None else {
1337
+ "SRTM": ["elevation", "slope"],
1338
+ "DW": [
1339
+ "DW_water", "DW_trees", "DW_grass", "DW_flooded_vegetation", "DW_crops",
1340
+ "DW_shrub_and_scrub", "DW_built", "DW_bare", "DW_snow_and_ice",
1341
+ ],
1342
+ "WC": [
1343
+ "WC_temporarycrops", "WC_maize", "WC_wintercereals", "WC_springcereals", "WC_irrigation",
1344
+ ],
1345
+ }
1346
+ self.pretraining_normalizing_dict = (
1347
+ pretraining_normalizing_dict
1348
+ if pretraining_normalizing_dict is not None
1349
+ else _default_pretraining_normalizing_dict()
1350
+ )
1351
+
1352
+ def band_layout(self) -> Dict[str, Any]:
1353
+ space_time_bands = self.s1_bands + self.s2_bands + ["NDVI"]
1354
+ time_bands = self.era5_bands + self.tc_bands + self.viirs_bands
1355
+ space_bands = self.srtm_bands + self.dw_bands + self.wc_bands
1356
+ static_dw_bands = [f"{band}_static" for band in self.dw_bands]
1357
+ static_wc_bands = [f"{band}_static" for band in self.wc_bands]
1358
+ static_bands = self.landscan_bands + self.location_bands + static_dw_bands + static_wc_bands
1359
+ static_band_groups = {
1360
+ "LS": self.landscan_bands,
1361
+ "location": self.location_bands,
1362
+ "DW_static": static_dw_bands,
1363
+ "WC_static": static_wc_bands,
1364
+ }
1365
+ return {
1366
+ "s1_bands": self.s1_bands,
1367
+ "s2_bands": self.s2_bands,
1368
+ "era5_bands": self.era5_bands,
1369
+ "tc_bands": self.tc_bands,
1370
+ "viirs_bands": self.viirs_bands,
1371
+ "srtm_bands": self.srtm_bands,
1372
+ "dw_bands": self.dw_bands,
1373
+ "wc_bands": self.wc_bands,
1374
+ "landscan_bands": self.landscan_bands,
1375
+ "location_bands": self.location_bands,
1376
+ "space_time_bands": space_time_bands,
1377
+ "time_bands": time_bands,
1378
+ "space_bands": space_bands,
1379
+ "static_bands": static_bands,
1380
+ "space_time_groups": _band_group_indices(space_time_bands, self.space_time_band_groups),
1381
+ "time_groups": _band_group_indices(time_bands, self.time_band_groups),
1382
+ "space_groups": _band_group_indices(space_bands, self.space_band_groups),
1383
+ "static_groups": _band_group_indices(static_bands, static_band_groups),
1384
+ "input_resolution_m": self.input_resolution_m,
1385
+ }
1386
 
1387
 
1388
  class GalileoPreTrainedModel(PreTrainedModel):
 
1407
  max_sequence_length=config.max_sequence_length,
1408
  freeze_projections=config.freeze_projections,
1409
  drop_path=config.drop_path,
1410
+ band_layout=config.band_layout(),
1411
  )
1412
  self.add_pooling_layer = add_pooling_layer and config.global_pool
1413
  self.post_init()
galileo-tiny-patch8/preprocessor_config.json CHANGED
@@ -5,5 +5,262 @@
5
  "patch_size": 8,
6
  "auto_map": {
7
  "AutoProcessor": "processing_galileo.GalileoProcessor"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  }
9
- }
 
5
  "patch_size": 8,
6
  "auto_map": {
7
  "AutoProcessor": "processing_galileo.GalileoProcessor"
8
+ },
9
+ "s1_bands": [
10
+ "VV",
11
+ "VH"
12
+ ],
13
+ "s2_bands": [
14
+ "B2",
15
+ "B3",
16
+ "B4",
17
+ "B5",
18
+ "B6",
19
+ "B7",
20
+ "B8",
21
+ "B8A",
22
+ "B11",
23
+ "B12"
24
+ ],
25
+ "era5_bands": [
26
+ "temperature_2m",
27
+ "total_precipitation_sum"
28
+ ],
29
+ "tc_bands": [
30
+ "def",
31
+ "soil",
32
+ "aet"
33
+ ],
34
+ "viirs_bands": [
35
+ "avg_rad"
36
+ ],
37
+ "srtm_bands": [
38
+ "elevation",
39
+ "slope"
40
+ ],
41
+ "dw_bands": [
42
+ "DW_water",
43
+ "DW_trees",
44
+ "DW_grass",
45
+ "DW_flooded_vegetation",
46
+ "DW_crops",
47
+ "DW_shrub_and_scrub",
48
+ "DW_built",
49
+ "DW_bare",
50
+ "DW_snow_and_ice"
51
+ ],
52
+ "wc_bands": [
53
+ "WC_temporarycrops",
54
+ "WC_maize",
55
+ "WC_wintercereals",
56
+ "WC_springcereals",
57
+ "WC_irrigation"
58
+ ],
59
+ "landscan_bands": [
60
+ "b1"
61
+ ],
62
+ "location_bands": [
63
+ "x",
64
+ "y",
65
+ "z"
66
+ ],
67
+ "space_time_band_groups": {
68
+ "S1": [
69
+ "VV",
70
+ "VH"
71
+ ],
72
+ "S2_RGB": [
73
+ "B2",
74
+ "B3",
75
+ "B4"
76
+ ],
77
+ "S2_Red_Edge": [
78
+ "B5",
79
+ "B6",
80
+ "B7"
81
+ ],
82
+ "S2_NIR_10m": [
83
+ "B8"
84
+ ],
85
+ "S2_NIR_20m": [
86
+ "B8A"
87
+ ],
88
+ "S2_SWIR": [
89
+ "B11",
90
+ "B12"
91
+ ],
92
+ "NDVI": [
93
+ "NDVI"
94
+ ]
95
+ },
96
+ "time_band_groups": {
97
+ "ERA5": [
98
+ "temperature_2m",
99
+ "total_precipitation_sum"
100
+ ],
101
+ "TC": [
102
+ "def",
103
+ "soil",
104
+ "aet"
105
+ ],
106
+ "VIIRS": [
107
+ "avg_rad"
108
+ ]
109
+ },
110
+ "space_band_groups": {
111
+ "SRTM": [
112
+ "elevation",
113
+ "slope"
114
+ ],
115
+ "DW": [
116
+ "DW_water",
117
+ "DW_trees",
118
+ "DW_grass",
119
+ "DW_flooded_vegetation",
120
+ "DW_crops",
121
+ "DW_shrub_and_scrub",
122
+ "DW_built",
123
+ "DW_bare",
124
+ "DW_snow_and_ice"
125
+ ],
126
+ "WC": [
127
+ "WC_temporarycrops",
128
+ "WC_maize",
129
+ "WC_wintercereals",
130
+ "WC_springcereals",
131
+ "WC_irrigation"
132
+ ]
133
+ },
134
+ "pretraining_normalizing_dict": {
135
+ "13": {
136
+ "mean": [
137
+ -11.728724389184965,
138
+ -18.85558188024017,
139
+ 1395.3408730676722,
140
+ 1338.4026921784578,
141
+ 1343.09883810357,
142
+ 1543.8607982512297,
143
+ 2186.2022069512263,
144
+ 2525.0932853316694,
145
+ 2410.3377187373408,
146
+ 2750.2854646886753,
147
+ 2234.911100061487,
148
+ 1474.5311266077113,
149
+ 0.2892116502999044
150
+ ],
151
+ "std": [
152
+ 4.887145774840316,
153
+ 5.730270320384293,
154
+ 917.7041440370853,
155
+ 913.2988423581528,
156
+ 1092.678723527555,
157
+ 1047.2206083460424,
158
+ 1048.0101611156767,
159
+ 1143.6903026819996,
160
+ 1098.979177731649,
161
+ 1204.472755085893,
162
+ 1145.9774063078878,
163
+ 980.2429840007796,
164
+ 0.2720939024500081
165
+ ]
166
+ },
167
+ "16": {
168
+ "mean": [
169
+ 673.0152819503361,
170
+ 5.930092668915115,
171
+ 0.10470439140978786,
172
+ 0.23965913270066183,
173
+ 0.08158044385860364,
174
+ 0.04246976254259546,
175
+ 0.11304392863520317,
176
+ 0.17329647890362473,
177
+ 0.0698981691616277,
178
+ 0.12130267132802142,
179
+ 0.04671318615236216,
180
+ 10.973119802517362,
181
+ 1.0927069179958768,
182
+ 1.6991394232855903,
183
+ 0.03720594618055555,
184
+ 1.3671352688259548
185
+ ],
186
+ "std": [
187
+ 983.0697298296237,
188
+ 8.167406789813247,
189
+ 0.18771647977504985,
190
+ 0.2368313455675914,
191
+ 0.08024268534756586,
192
+ 0.04045374496146404,
193
+ 0.11350342472061795,
194
+ 0.1279898111718168,
195
+ 0.12042341550438586,
196
+ 0.13602408145504347,
197
+ 0.043971116096060345,
198
+ 31.255340146970997,
199
+ 10.395974878206689,
200
+ 12.92380617159917,
201
+ 1.9285254295940466,
202
+ 11.612179775408928
203
+ ]
204
+ },
205
+ "6": {
206
+ "mean": [
207
+ 271.5674963541667,
208
+ 0.08554303677156568,
209
+ 657.3181260091111,
210
+ 692.1291795806885,
211
+ 562.781331880633,
212
+ 1.5647115934036673
213
+ ],
214
+ "std": [
215
+ 79.80828940314429,
216
+ 0.11669547098151486,
217
+ 704.0008695557707,
218
+ 925.0116126406431,
219
+ 453.2434022278578,
220
+ 7.513020170832818
221
+ ]
222
+ },
223
+ "18": {
224
+ "mean": [
225
+ 188.20315880851746,
226
+ 0.2804946561574936,
227
+ 0.11371652073860168,
228
+ 0.058778801321983334,
229
+ 0.10474256777763366,
230
+ 0.2396918488264084,
231
+ 0.08152248692512512,
232
+ 0.04248040814399719,
233
+ 0.11303179881572724,
234
+ 0.17326324067115784,
235
+ 0.06998309404850006,
236
+ 0.12122812910079957,
237
+ 0.04671641788482666,
238
+ 10.98456594619751,
239
+ 1.0968475807189941,
240
+ 1.6947754135131836,
241
+ 0.03320046615600586,
242
+ 1.3602827312469483
243
+ ],
244
+ "std": [
245
+ 1154.5919128300602,
246
+ 0.5276998078079327,
247
+ 0.7021637331734328,
248
+ 0.36528892213195063,
249
+ 0.17470213191865785,
250
+ 0.20411195416718833,
251
+ 0.0660782470089761,
252
+ 0.03380702424871257,
253
+ 0.09809195568521663,
254
+ 0.11292471052124119,
255
+ 0.09720748930233268,
256
+ 0.12912217763726777,
257
+ 0.0399973913151906,
258
+ 23.725471823867462,
259
+ 5.715238079725388,
260
+ 9.030481416228302,
261
+ 0.9950220242487364,
262
+ 7.754429123862099
263
+ ]
264
+ }
265
  }
266
+ }
galileo-tiny-patch8/processing_galileo.py CHANGED
@@ -4,7 +4,6 @@
4
  from __future__ import annotations
5
 
6
  import math
7
- from collections import OrderedDict
8
  from typing import Any, NamedTuple, Optional, Union
9
 
10
  import numpy as np
@@ -14,191 +13,7 @@ from transformers.feature_extraction_utils import BatchFeature
14
  from transformers.processing_utils import ProcessorMixin
15
  from transformers.utils import TensorType
16
 
17
-
18
- S1_BANDS = ["VV", "VH"]
19
- S2_BANDS = ["B2", "B3", "B4", "B5", "B6", "B7", "B8", "B8A", "B11", "B12"]
20
- ERA5_BANDS = ["temperature_2m", "total_precipitation_sum"]
21
- TC_BANDS = ["def", "soil", "aet"]
22
- VIIRS_BANDS = ["avg_rad"]
23
- SRTM_BANDS = ["elevation", "slope"]
24
- DW_BANDS = [
25
- "DW_water", "DW_trees", "DW_grass", "DW_flooded_vegetation", "DW_crops",
26
- "DW_shrub_and_scrub", "DW_built", "DW_bare", "DW_snow_and_ice",
27
- ]
28
- WC_BANDS = [
29
- "WC_temporarycrops", "WC_maize", "WC_wintercereals", "WC_springcereals", "WC_irrigation",
30
- ]
31
- LANDSCAN_BANDS = ["b1"]
32
- LOCATION_BANDS = ["x", "y", "z"]
33
- STATIC_DW_BANDS = [f"{x}_static" for x in DW_BANDS]
34
- STATIC_WC_BANDS = [f"{x}_static" for x in WC_BANDS]
35
-
36
- SPACE_TIME_BANDS = S1_BANDS + S2_BANDS + ["NDVI"]
37
- TIME_BANDS = ERA5_BANDS + TC_BANDS + VIIRS_BANDS
38
- SPACE_BANDS = SRTM_BANDS + DW_BANDS + WC_BANDS
39
- STATIC_BANDS = LANDSCAN_BANDS + LOCATION_BANDS + STATIC_DW_BANDS + STATIC_WC_BANDS
40
-
41
- SPACE_TIME_BANDS_GROUPS_IDX = OrderedDict({
42
- "S1": [SPACE_TIME_BANDS.index(b) for b in S1_BANDS],
43
- "S2_RGB": [SPACE_TIME_BANDS.index(b) for b in ["B2", "B3", "B4"]],
44
- "S2_Red_Edge": [SPACE_TIME_BANDS.index(b) for b in ["B5", "B6", "B7"]],
45
- "S2_NIR_10m": [SPACE_TIME_BANDS.index(b) for b in ["B8"]],
46
- "S2_NIR_20m": [SPACE_TIME_BANDS.index(b) for b in ["B8A"]],
47
- "S2_SWIR": [SPACE_TIME_BANDS.index(b) for b in ["B11", "B12"]],
48
- "NDVI": [SPACE_TIME_BANDS.index("NDVI")],
49
- })
50
- TIME_BAND_GROUPS_IDX = OrderedDict({
51
- "ERA5": [TIME_BANDS.index(b) for b in ERA5_BANDS],
52
- "TC": [TIME_BANDS.index(b) for b in TC_BANDS],
53
- "VIIRS": [TIME_BANDS.index(b) for b in VIIRS_BANDS],
54
- })
55
- SPACE_BAND_GROUPS_IDX = OrderedDict({
56
- "SRTM": [SPACE_BANDS.index(b) for b in SRTM_BANDS],
57
- "DW": [SPACE_BANDS.index(b) for b in DW_BANDS],
58
- "WC": [SPACE_BANDS.index(b) for b in WC_BANDS],
59
- })
60
- STATIC_BAND_GROUPS_IDX = OrderedDict({
61
- "LS": [STATIC_BANDS.index(b) for b in LANDSCAN_BANDS],
62
- "location": [STATIC_BANDS.index(b) for b in LOCATION_BANDS],
63
- "DW_static": [STATIC_BANDS.index(b) for b in STATIC_DW_BANDS],
64
- "WC_static": [STATIC_BANDS.index(b) for b in STATIC_WC_BANDS],
65
- })
66
-
67
-
68
- DEFAULT_MONTH = 5
69
-
70
- PRETRAINING_NORMALIZING_DICT = {
71
- "13": {
72
- "mean": [
73
- -11.728724389184965,
74
- -18.85558188024017,
75
- 1395.3408730676722,
76
- 1338.4026921784578,
77
- 1343.09883810357,
78
- 1543.8607982512297,
79
- 2186.2022069512263,
80
- 2525.0932853316694,
81
- 2410.3377187373408,
82
- 2750.2854646886753,
83
- 2234.911100061487,
84
- 1474.5311266077113,
85
- 0.2892116502999044,
86
- ],
87
- "std": [
88
- 4.887145774840316,
89
- 5.730270320384293,
90
- 917.7041440370853,
91
- 913.2988423581528,
92
- 1092.678723527555,
93
- 1047.2206083460424,
94
- 1048.0101611156767,
95
- 1143.6903026819996,
96
- 1098.979177731649,
97
- 1204.472755085893,
98
- 1145.9774063078878,
99
- 980.2429840007796,
100
- 0.2720939024500081,
101
- ],
102
- },
103
- "16": {
104
- "mean": [
105
- 673.0152819503361,
106
- 5.930092668915115,
107
- 0.10470439140978786,
108
- 0.23965913270066183,
109
- 0.08158044385860364,
110
- 0.04246976254259546,
111
- 0.11304392863520317,
112
- 0.17329647890362473,
113
- 0.0698981691616277,
114
- 0.12130267132802142,
115
- 0.04671318615236216,
116
- 10.973119802517362,
117
- 1.0927069179958768,
118
- 1.6991394232855903,
119
- 0.03720594618055555,
120
- 1.3671352688259548,
121
- ],
122
- "std": [
123
- 983.0697298296237,
124
- 8.167406789813247,
125
- 0.18771647977504985,
126
- 0.2368313455675914,
127
- 0.08024268534756586,
128
- 0.04045374496146404,
129
- 0.11350342472061795,
130
- 0.1279898111718168,
131
- 0.12042341550438586,
132
- 0.13602408145504347,
133
- 0.043971116096060345,
134
- 31.255340146970997,
135
- 10.395974878206689,
136
- 12.92380617159917,
137
- 1.9285254295940466,
138
- 11.612179775408928,
139
- ],
140
- },
141
- "6": {
142
- "mean": [
143
- 271.5674963541667,
144
- 0.08554303677156568,
145
- 657.3181260091111,
146
- 692.1291795806885,
147
- 562.781331880633,
148
- 1.5647115934036673,
149
- ],
150
- "std": [
151
- 79.80828940314429,
152
- 0.11669547098151486,
153
- 704.0008695557707,
154
- 925.0116126406431,
155
- 453.2434022278578,
156
- 7.513020170832818,
157
- ],
158
- },
159
- "18": {
160
- "mean": [
161
- 188.20315880851746,
162
- 0.2804946561574936,
163
- 0.11371652073860168,
164
- 0.058778801321983334,
165
- 0.10474256777763366,
166
- 0.2396918488264084,
167
- 0.08152248692512512,
168
- 0.04248040814399719,
169
- 0.11303179881572724,
170
- 0.17326324067115784,
171
- 0.06998309404850006,
172
- 0.12122812910079957,
173
- 0.04671641788482666,
174
- 10.98456594619751,
175
- 1.0968475807189941,
176
- 1.6947754135131836,
177
- 0.03320046615600586,
178
- 1.3602827312469483,
179
- ],
180
- "std": [
181
- 1154.5919128300602,
182
- 0.5276998078079327,
183
- 0.7021637331734328,
184
- 0.36528892213195063,
185
- 0.17470213191865785,
186
- 0.20411195416718833,
187
- 0.0660782470089761,
188
- 0.03380702424871257,
189
- 0.09809195568521663,
190
- 0.11292471052124119,
191
- 0.09720748930233268,
192
- 0.12912217763726777,
193
- 0.0399973913151906,
194
- 23.725471823867462,
195
- 5.715238079725388,
196
- 9.030481416228302,
197
- 0.9950220242487364,
198
- 7.754429123862099,
199
- ],
200
- },
201
- }
202
 
203
 
204
  class MaskedOutput(NamedTuple):
@@ -257,7 +72,19 @@ def construct_galileo_input(
257
  latlon: torch.Tensor | None = None,
258
  months: torch.Tensor | None = None,
259
  normalize: bool = False,
 
260
  ) -> MaskedOutput:
 
 
 
 
 
 
 
 
 
 
 
261
  space_time_inputs = [s1, s2]
262
  time_inputs = [era5, tc, viirs]
263
  space_inputs = [srtm, dw, wc]
@@ -285,56 +112,56 @@ def construct_galileo_input(
285
  t = timesteps_list[0] if timesteps_list else 1
286
  h, w = (height_list[0], width_list[0]) if height_list else (1, 1)
287
 
288
- s_t_x = torch.zeros((h, w, t, len(SPACE_TIME_BANDS)), dtype=torch.float, device=device)
289
- s_t_m = torch.ones((h, w, t, len(SPACE_TIME_BANDS_GROUPS_IDX)), dtype=torch.float, device=device)
290
- sp_x = torch.zeros((h, w, len(SPACE_BANDS)), dtype=torch.float, device=device)
291
- sp_m = torch.ones((h, w, len(SPACE_BAND_GROUPS_IDX)), dtype=torch.float, device=device)
292
- t_x = torch.zeros((t, len(TIME_BANDS)), dtype=torch.float, device=device)
293
- t_m = torch.ones((t, len(TIME_BAND_GROUPS_IDX)), dtype=torch.float, device=device)
294
- st_x = torch.zeros((len(STATIC_BANDS)), dtype=torch.float, device=device)
295
- st_m = torch.ones((len(STATIC_BAND_GROUPS_IDX)), dtype=torch.float, device=device)
296
 
297
- for x, bands_list, group_key in zip([s1, s2], [S1_BANDS, S2_BANDS], ["S1", "S2"]):
298
  if x is not None:
299
- indices = [idx for idx, val in enumerate(SPACE_TIME_BANDS) if val in bands_list]
300
- groups_idx = [idx for idx, key in enumerate(SPACE_TIME_BANDS_GROUPS_IDX) if group_key in key]
301
  s_t_x[:, :, :, indices] = x
302
  s_t_m[:, :, :, groups_idx] = 0
303
 
304
  for x, bands_list, group_key in zip(
305
- [srtm, dw, wc], [SRTM_BANDS, DW_BANDS, WC_BANDS], ["SRTM", "DW", "WC"]
306
  ):
307
  if x is not None:
308
- indices = [idx for idx, val in enumerate(SPACE_BANDS) if val in bands_list]
309
- groups_idx = [idx for idx, key in enumerate(SPACE_BAND_GROUPS_IDX) if group_key in key]
310
  sp_x[:, :, indices] = x
311
  sp_m[:, :, groups_idx] = 0
312
 
313
  for x, bands_list, group_key in zip(
314
- [era5, tc, viirs], [ERA5_BANDS, TC_BANDS, VIIRS_BANDS], ["ERA5", "TC", "VIIRS"]
315
  ):
316
  if x is not None:
317
- indices = [idx for idx, val in enumerate(TIME_BANDS) if val in bands_list]
318
- groups_idx = [idx for idx, key in enumerate(TIME_BAND_GROUPS_IDX) if group_key in key]
319
  t_x[:, indices] = x
320
  t_m[:, groups_idx] = 0
321
 
322
  for x, bands_list, group_key in zip(
323
- [landscan, latlon], [LANDSCAN_BANDS, LOCATION_BANDS], ["LS", "location"]
324
  ):
325
  if x is not None:
326
  if group_key == "location":
327
  x = torch.as_tensor(to_cartesian(float(x[0]), float(x[1])), device=device)
328
- indices = [idx for idx, val in enumerate(STATIC_BANDS) if val in bands_list]
329
- groups_idx = [idx for idx, key in enumerate(STATIC_BAND_GROUPS_IDX) if group_key in key]
330
  st_x[indices] = x
331
  st_m[groups_idx] = 0
332
 
333
  if months is None:
334
- months = torch.ones((t), dtype=torch.long, device=device) * DEFAULT_MONTH
335
 
336
  if normalize:
337
- normalizer = PretrainingNormalizer(PRETRAINING_NORMALIZING_DICT)
338
  s_t_x = torch.from_numpy(normalizer(s_t_x.cpu().numpy())).to(device)
339
  sp_x = torch.from_numpy(normalizer(sp_x.cpu().numpy())).to(device)
340
  t_x = torch.from_numpy(normalizer(t_x.cpu().numpy())).to(device)
@@ -367,11 +194,48 @@ class GalileoProcessor(ProcessorMixin):
367
  "months",
368
  ]
369
 
370
- def __init__(self, normalize: bool = True, default_month: int = 6, patch_size: int = 8, **kwargs):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  super().__init__(**kwargs)
372
  self.normalize = normalize
373
  self.default_month = default_month
374
  self.patch_size = patch_size
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
 
376
  def __call__(
377
  self,
@@ -418,6 +282,7 @@ class GalileoProcessor(ProcessorMixin):
418
  latlon=_to_tensor(latlon),
419
  months=months,
420
  normalize=normalize,
 
421
  )
422
 
423
  if masked_output.space_time_x.dim() == 4:
 
4
  from __future__ import annotations
5
 
6
  import math
 
7
  from typing import Any, NamedTuple, Optional, Union
8
 
9
  import numpy as np
 
13
  from transformers.processing_utils import ProcessorMixin
14
  from transformers.utils import TensorType
15
 
16
+ from .modeling_galileo import GalileoConfig
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
 
19
  class MaskedOutput(NamedTuple):
 
72
  latlon: torch.Tensor | None = None,
73
  months: torch.Tensor | None = None,
74
  normalize: bool = False,
75
+ band_config: GalileoConfig | None = None,
76
  ) -> MaskedOutput:
77
+ band_config = band_config or GalileoConfig()
78
+ bands = band_config.band_layout()
79
+ space_time_bands = bands["space_time_bands"]
80
+ space_time_groups = bands["space_time_groups"]
81
+ time_bands = bands["time_bands"]
82
+ time_groups = bands["time_groups"]
83
+ space_bands = bands["space_bands"]
84
+ space_groups = bands["space_groups"]
85
+ static_bands = bands["static_bands"]
86
+ static_groups = bands["static_groups"]
87
+
88
  space_time_inputs = [s1, s2]
89
  time_inputs = [era5, tc, viirs]
90
  space_inputs = [srtm, dw, wc]
 
112
  t = timesteps_list[0] if timesteps_list else 1
113
  h, w = (height_list[0], width_list[0]) if height_list else (1, 1)
114
 
115
+ s_t_x = torch.zeros((h, w, t, len(space_time_bands)), dtype=torch.float, device=device)
116
+ s_t_m = torch.ones((h, w, t, len(space_time_groups)), dtype=torch.float, device=device)
117
+ sp_x = torch.zeros((h, w, len(space_bands)), dtype=torch.float, device=device)
118
+ sp_m = torch.ones((h, w, len(space_groups)), dtype=torch.float, device=device)
119
+ t_x = torch.zeros((t, len(time_bands)), dtype=torch.float, device=device)
120
+ t_m = torch.ones((t, len(time_groups)), dtype=torch.float, device=device)
121
+ st_x = torch.zeros((len(static_bands)), dtype=torch.float, device=device)
122
+ st_m = torch.ones((len(static_groups)), dtype=torch.float, device=device)
123
 
124
+ for x, bands_list, group_key in zip([s1, s2], [bands["s1_bands"], bands["s2_bands"]], ["S1", "S2"]):
125
  if x is not None:
126
+ indices = [idx for idx, val in enumerate(space_time_bands) if val in bands_list]
127
+ groups_idx = [idx for idx, key in enumerate(space_time_groups) if group_key in key]
128
  s_t_x[:, :, :, indices] = x
129
  s_t_m[:, :, :, groups_idx] = 0
130
 
131
  for x, bands_list, group_key in zip(
132
+ [srtm, dw, wc], [bands["srtm_bands"], bands["dw_bands"], bands["wc_bands"]], ["SRTM", "DW", "WC"]
133
  ):
134
  if x is not None:
135
+ indices = [idx for idx, val in enumerate(space_bands) if val in bands_list]
136
+ groups_idx = [idx for idx, key in enumerate(space_groups) if group_key in key]
137
  sp_x[:, :, indices] = x
138
  sp_m[:, :, groups_idx] = 0
139
 
140
  for x, bands_list, group_key in zip(
141
+ [era5, tc, viirs], [bands["era5_bands"], bands["tc_bands"], bands["viirs_bands"]], ["ERA5", "TC", "VIIRS"]
142
  ):
143
  if x is not None:
144
+ indices = [idx for idx, val in enumerate(time_bands) if val in bands_list]
145
+ groups_idx = [idx for idx, key in enumerate(time_groups) if group_key in key]
146
  t_x[:, indices] = x
147
  t_m[:, groups_idx] = 0
148
 
149
  for x, bands_list, group_key in zip(
150
+ [landscan, latlon], [bands["landscan_bands"], bands["location_bands"]], ["LS", "location"]
151
  ):
152
  if x is not None:
153
  if group_key == "location":
154
  x = torch.as_tensor(to_cartesian(float(x[0]), float(x[1])), device=device)
155
+ indices = [idx for idx, val in enumerate(static_bands) if val in bands_list]
156
+ groups_idx = [idx for idx, key in enumerate(static_groups) if group_key in key]
157
  st_x[indices] = x
158
  st_m[groups_idx] = 0
159
 
160
  if months is None:
161
+ months = torch.ones((t), dtype=torch.long, device=device) * band_config.default_month
162
 
163
  if normalize:
164
+ normalizer = PretrainingNormalizer(band_config.pretraining_normalizing_dict)
165
  s_t_x = torch.from_numpy(normalizer(s_t_x.cpu().numpy())).to(device)
166
  sp_x = torch.from_numpy(normalizer(sp_x.cpu().numpy())).to(device)
167
  t_x = torch.from_numpy(normalizer(t_x.cpu().numpy())).to(device)
 
194
  "months",
195
  ]
196
 
197
+ def __init__(
198
+ self,
199
+ normalize: bool = True,
200
+ default_month: int = 6,
201
+ patch_size: int = 8,
202
+ s1_bands: Optional[list[str]] = None,
203
+ s2_bands: Optional[list[str]] = None,
204
+ era5_bands: Optional[list[str]] = None,
205
+ tc_bands: Optional[list[str]] = None,
206
+ viirs_bands: Optional[list[str]] = None,
207
+ srtm_bands: Optional[list[str]] = None,
208
+ dw_bands: Optional[list[str]] = None,
209
+ wc_bands: Optional[list[str]] = None,
210
+ landscan_bands: Optional[list[str]] = None,
211
+ location_bands: Optional[list[str]] = None,
212
+ space_time_band_groups: Optional[dict[str, list[str]]] = None,
213
+ time_band_groups: Optional[dict[str, list[str]]] = None,
214
+ space_band_groups: Optional[dict[str, list[str]]] = None,
215
+ pretraining_normalizing_dict: Optional[dict[str, dict[str, list[float]]]] = None,
216
+ **kwargs,
217
+ ):
218
  super().__init__(**kwargs)
219
  self.normalize = normalize
220
  self.default_month = default_month
221
  self.patch_size = patch_size
222
+ self.band_config = GalileoConfig(
223
+ default_month=default_month,
224
+ s1_bands=s1_bands,
225
+ s2_bands=s2_bands,
226
+ era5_bands=era5_bands,
227
+ tc_bands=tc_bands,
228
+ viirs_bands=viirs_bands,
229
+ srtm_bands=srtm_bands,
230
+ dw_bands=dw_bands,
231
+ wc_bands=wc_bands,
232
+ landscan_bands=landscan_bands,
233
+ location_bands=location_bands,
234
+ space_time_band_groups=space_time_band_groups,
235
+ time_band_groups=time_band_groups,
236
+ space_band_groups=space_band_groups,
237
+ pretraining_normalizing_dict=pretraining_normalizing_dict,
238
+ )
239
 
240
  def __call__(
241
  self,
 
282
  latlon=_to_tensor(latlon),
283
  months=months,
284
  normalize=normalize,
285
+ band_config=self.band_config,
286
  )
287
 
288
  if masked_output.space_time_x.dim() == 4: