Download scripts/fake_data.py from OneScience-Group/SkySense: direct link, hf CLI and curl.
- Browser
- Download file 4.15 kB
-
https://huggingface.co/OneScience-Group/SkySense/resolve/main/scripts/fake_data.py
- Command line
-
hf download hf://OneScience-Group/SkySense/scripts/fake_data.py
-
curl -L -o fake_data.py https://huggingface.co/OneScience-Group/SkySense/resolve/main/scripts/fake_data.py
4.15 kB
| """Generate deterministic SkySense-format data for connectivity tests.""" | |
| import argparse | |
| from pathlib import Path | |
| import numpy as np | |
| import yaml | |
| ROOT = Path(__file__).resolve().parents[1] | |
| def load_config(): | |
| with (ROOT / "conf" / "config.yaml").open(encoding="utf-8") as handle: | |
| return yaml.safe_load(handle) | |
| def make_split(path, count, config, seed): | |
| rng = np.random.default_rng(seed) | |
| data = config["data"] | |
| hr_size = data["hr_size"] | |
| low_size = data["s2_size"] | |
| if low_size != data["s1_size"]: | |
| raise ValueError("The fake generator expects equal S1/S2 grid sizes") | |
| y, x = np.mgrid[0:hr_size, 0:hr_size].astype(np.float32) / (hr_size - 1) | |
| low_y, low_x = np.mgrid[0:low_size, 0:low_size].astype(np.float32) / (low_size - 1) | |
| land = np.stack([x, y, np.sin(4 * np.pi * x) * np.cos(3 * np.pi * y)], axis=0) | |
| hr = np.empty((count, data["hr_timesteps"], data["hr_channels"], hr_size, hr_size), np.float32) | |
| s2 = np.empty((count, data["s2_timesteps"], data["s2_channels"], low_size, low_size), np.float32) | |
| s1 = np.empty((count, data["s1_timesteps"], data["s1_channels"], low_size, low_size), np.float32) | |
| for sample in range(count): | |
| phase = rng.uniform(0, 2 * np.pi) | |
| hr[sample, 0] = land + rng.normal(0, 0.04, land.shape) | |
| for time in range(data["s2_timesteps"]): | |
| seasonal = np.sin(2 * np.pi * time / data["s2_timesteps"] + phase) | |
| s2[sample, time] = np.stack([ | |
| 0.5 + 0.2 * np.sin((band + 1) * low_x + phase) + 0.1 * seasonal * low_y | |
| for band in range(data["s2_channels"]) | |
| ]) + rng.normal(0, 0.025, (data["s2_channels"], low_size, low_size)) | |
| for time in range(data["s1_timesteps"]): | |
| seasonal = np.cos(2 * np.pi * time / data["s1_timesteps"] + phase) | |
| s1[sample, time, 0] = -0.6 + 0.3 * np.sin(4 * np.pi * low_x) * np.cos(3 * np.pi * low_y) + 0.1 * seasonal | |
| s1[sample, time, 1] = -0.8 + 0.2 * low_y - 0.1 * seasonal | |
| hr[sample] = np.clip(hr[sample], -1, 1) | |
| s2[sample] = np.clip(s2[sample], 0, 1) | |
| dates_hr = rng.integers(0, 365, size=(count, data["hr_timesteps"]), dtype=np.int64) | |
| dates_s2 = rng.integers(0, 365, size=(count, data["s2_timesteps"]), dtype=np.int64) | |
| dates_s1 = rng.integers(0, 365, size=(count, data["s1_timesteps"]), dtype=np.int64) | |
| region = rng.integers(0, config["model"]["num_regions"], size=count, dtype=np.int64) | |
| indices = np.linspace(0, low_size - 1, hr_size).round().astype(int) | |
| s2_hr = s2[:, :, 3].mean(axis=1)[:, indices][:, :, indices] | |
| s1_hr = s1[:, :, 0].mean(axis=1)[:, indices][:, :, indices] | |
| signal = hr[:, 0, 0] + 0.35 * s2_hr - 0.2 * s1_hr | |
| bins = np.quantile(signal, np.linspace(0, 1, data["num_classes"] + 1)[1:-1]) | |
| labels = np.digitize(signal, bins).astype(np.int64) | |
| np.savez_compressed( | |
| path, | |
| hr=hr, | |
| s2=s2, | |
| s1=s1, | |
| dates_hr=dates_hr, | |
| dates_s2=dates_s2, | |
| dates_s1=dates_s1, | |
| region=region, | |
| labels=labels, | |
| data_source=np.asarray("synthetic"), | |
| protocol=np.asarray(config["data"]["protocol"]), | |
| band_order_hr=np.asarray(["R", "G", "B"]), | |
| band_order_s2=np.asarray(["B2", "B3", "B4", "B5", "B6", "B7", "B8", "B8A", "B11", "B12"]), | |
| band_order_s1=np.asarray(["VV", "VH"]), | |
| ) | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--force", action="store_true") | |
| args = parser.parse_args() | |
| config = load_config() | |
| data_dir = ROOT / config["data"]["root"] | |
| data_dir.mkdir(parents=True, exist_ok=True) | |
| outputs = [("train.npz", config["data"]["train_samples"]), ("test.npz", config["data"]["test_samples"])] | |
| for offset, (name, count) in enumerate(outputs): | |
| target = data_dir / name | |
| if args.force or not target.exists(): | |
| make_split(target, count, config, config["seed"] + offset) | |
| print( | |
| f"generated={target.relative_to(ROOT)} samples={count} " | |
| f"data_source=synthetic protocol={config['data']['protocol']}" | |
| ) | |
| if __name__ == "__main__": | |
| main() | |